CAS单点登陆

715 阅读4分钟

单点登录(Single Sign On)

什么是CAS

答:CAS Client处理用户请求,需要登陆,则重定向到CAS Server ,如果已登陆,验证client的ticket票据.

HTTPS认证

答:默认使用HTTPS协议,修改配置可以使用HTTPS 修改WEB-INF下cas的xml配置文件

第一,cas的WEB-INF/deployerConfigContext.xml
增加requireSecure=false 即不需要安全验证
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient" p:requireSecure="false"/>

第二,cas的/WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml
<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
    p:cookieSecure="true"
    p:cookieMaxAge="-1"
    p:cookieName="CASTGC"
    p:cookiePath="/cas" />
true改为false,-1表示cookie无生命周期,关闭窗口就死,改3600表示一小时不需要登陆验证

第三,cas的WEB-INF/spring-configuration/warnCookieGenerator.xml
<bean id="warnCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
    p:cookieSecure="true"
    p:cookieMaxAge="-1"
    p:cookieName="CASPRIVACY"
    p:cookiePath="/cas" />
改false,改3600

原生CAS demo配置

pom包括client和servlet

本地自测: 设置9001tomcat端口 9100 cas服务器端口

web.xml:

filter过滤器:单点登陆的拦截

单点登出和单点登录

用户认证过滤: 必选配置

        CASFilter 用户,cas包的认证类下的
        casServletLoginUrl Cas服务端URL 需要重定向的地址
        serverName 需要跳转回的客户端的地址

票据验证过滤 必选配置

        CAS Validation Filter 
        服务端URL以及跳转回地址

单点登出配 可选配置

    CAS Single Sign Out Filter 

过滤器-获得用户名 可选配置

    CAS HttpServletRequest Wrapper Filter

过滤器-获得用户对象 可选配置

    CAS Assertion Thread Local Filter

以上二者区别: GetRemoteUser仅获取用户名的字符串,getUserPrincipal可以获得完整的用户对象,实现类可以获得有关用户的各种信息,其中之一的属性就是getName()

添加账密数据源

修改cas服务端中web-inf下deployerConfigContext.xml

1.修改bean的注入源为dataSource注入,

2.使用MD5解密,

3.入口Bean: passwordEncoder

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
   		  p:driverClass="com.mysql.jdbc.Driver"  
   		  p:jdbcUrl="jdbc:mysql://127.0.0.1:3306/pinyougoudb?characterEncoding=utf8"  
   		  p:user="root"  
   		  p:password="123456" /> 
<bean id="passwordEncoder" 
class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"  
   	c:encodingAlgorithm="MD5"  
   	p:characterEncoding="UTF-8" />  
<bean id="dbAuthHandler"  
   	  class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"  
   	  p:dataSource-ref="dataSource"  
   	  p:sql="select password from tb_user where username = ?"  
   	  p:passwordEncoder-ref="passwordEncoder"/>  

修改

    <entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />

<entry key-ref="dbAuthHandler" value-ref="primaryPrincipalResolver"/>

Tips:

记得增加相关jar包到cas

修改CAS默认错误提示

    目录:WEB-INF\classes目录下的messages.properties文件中
    用户名不存在
    authenticationFailure.AccountNotFoundException=\u7528\u6237\u4E0D\u5B58\u5728
    密码错误
    authenticationFailure.FailedLoginException=\u5BC6\u7801\u9519\u8BEF.
    国际化语言默认改中文
    cas-servlet.xml
        <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" p:defaultLocale="zh_CN" />

CAS与Spring Security集成

1.导入spring和spring-security依赖

spring-security-cas

cas-client-core(排除依赖slf4j)

2.使用spring-security.xml,而不是web.xml

    <?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
	
	<http pattern="\login.html" security=none />
	<http pattern="\error.html" security=none />
	<!--   entry-point-ref  入口点引用,选择使用cas方案 -->
	<http use-expressions="false" entry-point-ref="casProcessingFilterEntryPoint">  
	<!--   true>>hasrole("ROLE_USER") -->
        <intercept-url pattern="/**" access="ROLE_USER"/>   
        <csrf disabled="true"/>  
        <!-- 替换web.xml的cas过滤器 
        custom-filter为过滤器, position 表示将过滤器放在指定的位置[spring security的内置过滤器]上,before表示放在指定位置之前  ,after表示放在指定的位置之后  -->           
        <custom-filter ref="casAuthenticationFilter"  position="CAS_FILTER" />      
        <!--两个单点登出的过滤器的区别是什么? cas和security分工,看下面-->
        <custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/>  
        <custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/>  
    </http>
    
  	<!-- CAS入口点 开始 -->
    <beans:bean id="casProcessingFilterEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">  
        <!-- 单点登录服务器登录URL -->  
        <beans:property name="loginUrl" value="http://localhost:9100/cas/login"/>  
        <beans:property name="serviceProperties" ref="serviceProperties"/>  
    </beans:bean>      
    <beans:bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">  
        <!--service 配置自身工程的根地址+/login/cas   -->  
        <beans:property name="service" value="http://localhost:9003/login/cas"/>
    </beans:bean>  
    <!-- CAS入口点 结束 -->
   
    <!-- 认证过滤器 开始 -->
    <beans:bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">  
        <beans:property name="authenticationManager" ref="authenticationManager"/>  
    </beans:bean>  
		<!-- 认证管理器 -->
	<authentication-manager alias="authenticationManager">
		<authentication-provider  ref="casAuthenticationProvider">
		</authentication-provider>
	</authentication-manager>
		<!-- 认证提供者 -->
	<beans:bean id="casAuthenticationProvider"     class="org.springframework.security.cas.authentication.CasAuthenticationProvider">  
        <beans:property name="authenticationUserDetailsService">  
            <beans:bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">  
                <beans:constructor-arg ref="userDetailsService" />  
            </beans:bean>  
        </beans:property>  
        <!--得到的原来的客户端URL-->
        <beans:property name="serviceProperties" ref="serviceProperties"/>  
        <!-- ticketValidator 为票据验证器 -->
        <beans:property name="ticketValidator">  
            <beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">  
                <beans:constructor-arg index="0" value="http://localhost:9100/cas"/>  
            </beans:bean>  
        </beans:property>  
        <!--这个不用管,就是内置的一个属性,网上也没查到相关资料-->
        <beans:property name="key" value="an_id_for_this_auth_provider_only"/> 
    </beans:bean>        
   		 <!-- 认证类 -->
	<beans:bean id="userDetailsService" class="cn.itcast.demo.service.UserDetailServiceImpl"/>  
	
	<!-- 认证过滤器 结束 -->
	<!-- 2个单点登出  开始  cas和security分工 -->     
    <beans:bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>          
    <beans:bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">  
        <beans:constructor-arg value="http://localhost:9100/cas/logout?service=http://www.baidu.com"/>  
        <beans:constructor-arg>  
            <beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>  
        </beans:constructor-arg>  
        <!--封装真实地址-->
        <beans:property name="filterProcessesUrl" value="/logout/cas"/>  
    </beans:bean>  
    <!-- 单点登出  结束 -->  
</beans:beans>