单点登录(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>