CAS是一个单点登录框架,开始是由耶鲁大学的一个组织开发,后来由apereo管理。
CAS是遵循apache 2.0协议开源框架。https://github.com/apereo/cas/releases
单点登录:Single Sign On,简称SSO,SSO使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
- 登录CAS系统流程图
Ø 浏览器第一次访问系统A(CAS客户端)。
1.系统A去Cookie中取JSESSION,Cookie中没有JSESSION(TGC),说明系统A未登录。
2.系统A重定向到CAS服务端,CAS服务端检查是否已生成TGT(浏览器和客户端之间的全局会话),没有TGT,说明当前打开的浏览器没有进行过登录操作。
3.重定向到CAS服务端登录界面,输入用户名密码登录系统。
4. 登录系统成功后,服务端和客户端建立全局会话TGT,TGT信息保存在服务端,客户端生成TGC,TGC在客户端A的域名和服务端的域名下都会保存。
Ø 浏览器第一次访问系统B(CAS客户端),系统A登录成功后,不关闭浏览器的情况下。
1. 系统B去Cookie中取JSESSION,Cookie中没有JSESSION,说明系统B未登录。
2. 系统B重定向到CAS服务端,CAS服务端检查是否已生成TGT,TGT在系统A登录后已存在,CAS服务端读取浏览器中的TGC,此时TGC已经存在,则说明已经登录过CAS系统,附带上认证令牌ST重定向到系统B,系统B收到ST后把ST传递给服务端,服务端验证ST合法性,验证通过后服务端传递登录的用户信息给系统B。
Ø 浏览器第二次访问系统A(CAS客户端),系统A第一次登录成功后,不关闭浏览器的情况下。
1. 系统A去Cookie中取JSESSION,Cookie中已有JSESSION,说明系统A已经录过。
2.系统A重定向到CAS服务端,申请认证令牌ST,附带上认证令牌ST重定向到系统A,系统A收到ST后把ST传递给服务端,服务端验证ST合法性,验证通过后服务端传递登录的用户信息给系统A。
名词解释:
u TGT:客户端和服务端生成的全局会话,只要有客户端登录成功,就会在服务端生成TGT
u TGC:保存在客户端的Cookie,在登录过的客户端和服务端的域名下都会保存,名称是JSESSION内容是TGT的ID。
u ST:服务端生成的随机字符串。
- 去除CAS框架的https验证
2.找到文件“/WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml”,找到其中id为“ticketGrantingTicketCookieGenerator”的bean,修改p:cookieSecure=“false”,取消CAS的安全验证;p:cookieMaxAge=”-1”修改为p:cookieMaxAge=”3600”,此属性是设置COOKIE的最大生命周期,-1为无生命周期,即只在当前打开的窗口有效,关闭或重新打开其它窗口,仍会要求验证。可以根据需要修改为大于0的数字,比如3600等,意思是在3600秒内,打开任意窗口,都不需要验证。
3.找到文件“/WEB-INF/spring-configuration/warnCookieGenerator.xml”,找到其中id为“warnCookieGenerator”的bean,修改属性p:cookieSecure=“false”,p:cookieMaxAge=”3600”。
- 默认用户名和密码修改,以及数据库连接
找到文件“/WEB-INF/deployerConfigContext.xml”,找到如下代码,用户名和密码是:admin,1
<!-- 用户名密码 --> <bean id="primaryAuthenticationHandler"class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler"> <property name="users"> <map> <entry key="admin" value="1"/> </map> </property> </bean> 自定义用户名密码验证,修改配置如下: <bean id="primaryAuthenticationHandler" class="org.jasig.cas.authentication.MyAcceptUsersAuthenticationHandler"> 其中org.jasig.cas.authentication.MyAcceptUsersAuthenticationHandler为自己定义的类,代码内容如下: import java.security.GeneralSecurityException; import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;import org.jasig.cas.authentication.principal.SimplePrincipal; import javax.security.auth.login.FailedLoginException; public class MyAcceptUsersAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {@Override protected final HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential) throws GeneralSecurityException, PreventedException { // 获取表单提交的用户名和密码 final String userName = credential.getUsername(); final String password = credential.getPassword(); // 逻辑验证.... if(...){ // 登录成功 return createHandlerResult(credential, new SimplePrincipal(userName), null); }else{ // 登录失败 throw new FailedLoginException(""); } } |
<!-- 配置数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
p:driverClass="com.mysql.jdbc.Driver"
p:jdbcUrl="jdbc:mysql://localhost:3306/test..."
p:user="root"
p:password="root"/>
<!--配置密码加密方式-->
<propertyname="passwordEncoder">
<beanclass="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
<constructor-argvalue="SHA"/>
</bean>
</property>
<!-- 使用数据库中的信息对登录进行验证 -->
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="sql" value="select password from userinfo where userName=?" />
<property name="dataSource" ref="dataSource"/>
</bean>
资源地址:https://github.com/apereo/cas/releases?after=v4.0.5
- 客户端Tomcat中web.xml配置
<!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置--> <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener> <filter> <filter-name>CAS Single Sign Out Filter</filter-name> <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置 --> <!-- 核心过滤器 --> <filter-name>CAS Filter</filter-name> <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> <init-param> <param-name>casServerLoginUrl</param-name>--> <param-value>http://server.cas.com:9001/cas-server</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://cas-app2.com:9101/sso</param-value> </init-param> </filter> <filter-mapping> <filter-name>CAS Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 核心过滤器 --> <!-- 该过滤器负责对Ticket的校验工作,必须启用它 --> <filter><filter-name>CAS Validation Filter</filter-name> <filter-class> org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class> <init-param> <param-name>casServerUrlPrefix</param-name> <!--<param-value>http://server.cas.com:9001/cas-server</param-value>--> <param-value>http://www.baidu.com</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://cas-app2.com:9101/sso</param-value> </init-param> </filter> <filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> <!-- 不需要登录验证的地址 --> <param-name>excludedPages</param-name> <param-value>http://cas-app2.com:9101/sso/login_toLogin.do</param-value> </init-param> </filter-mapping> <!-- 该过滤器负责对Ticket的校验工作,必须启用它 --> <!-- -->
|