从结构上看,CAS 包含两个部分: CAS Server 和 CAS Client。
CAS Server 需要独立部署,主要负责对用户的认证工作;
CAS Client 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 CAS Server。
工作流程:
Web Browser意思是浏览器,也就是指用户。CAS Client指的是我们项目中的模块,比如用户模块,订单模块等。
当用户访问CAS Client时,会重定向到CAS Server中,去进行用户认证,也就是登录操作。因此,用户实际登录是在CAS Server中登录的。
用户登录成功后,CAS Server会随机产生并发送一个票据到CAS Client。
当用户再次访问CAS Client时,也就是其他模块时,会携带票据到CAS Server中去验证这个用户是否有效
有效的话会将用户信息返回给CAS Client,此时就可以访问。
如果无效,会再次重定向到CAS Server中进行登录。
CAS配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!--登录认证过滤器-->
<filter>
<filter-name>CASFilter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>http://192.168.188.131:9100/cas/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:9001</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CASFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 凭据认证过滤器-->
<filter>
<filter-name>casValidationFilter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>http://192.168.188.131:9100/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:9001</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>casValidationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 针对HttpservletRequest请求-->
<filter>
<filter-name>CasHttpRequestFilter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CasHttpRequestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 获取登录用户名的过滤器-->
<filter>
<filter-name>casLocalFilter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>casLocalFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 退出登录监听器过滤器-->
<listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<filter>
<filter-name>casSingOutFilter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>casSingOutFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
CAS与Spring Security集成:
<?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="/css/**" security="none"></http>
<http pattern="/data/**" security="none"></http>
<http pattern="/fonts/**" security="none"></http>
<http pattern="/img/**" security="none"></http>
<http pattern="/js/**" security="none"></http>
<http pattern="/plugins/**" security="none"></http>
<http pattern="/register.html" security="none"></http>
<http pattern="/user/add.do" security="none"></http>
<http pattern="/user/sendCode.do" security="none"></http>
<!-- entry-point-ref 入口点引用 -->
<http use-expressions="false" entry-point-ref="casProcessingFilterEntryPoint">
<intercept-url pattern="/**" access="ROLE_USER"/>
<csrf disabled="true"/>
<!-- custom-filter为过滤器, position 表示将过滤器放在指定的位置上,before表示放在指定位置之前 ,after表示放在指定的位置之后 -->
<custom-filter ref="casAuthenticationFilter" position="CAS_FILTER" />
<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://192.168.188.129:8080/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://127.0.0.1:9106/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>
<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://192.168.188.129:8080/cas"/>
</beans:bean>
</beans:property>
<beans:property name="key" value="an_id_for_this_auth_provider_only"/>
</beans:bean>
<!-- 认证类 -->
<beans:bean id="userDetailsService" class="com.offcn.user.service.UserDetailServiceImpl"/>
<!-- 认证过滤器 结束 -->
<!-- 单点登出 开始 -->
<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://192.168.188.129:8080/cas/logout?service=http://127.0.0.1:9103/index.html"/>
<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>