单点登录(Single Sign On),简称为 SSO:用户只需要登录一次就可以访问所有相互信任的应用用系统。
从结构上看, CAS 包含两个部分: CAS Server 和 CAS Client。 CAS Server 需要独立部署,
主要负责对用户的认证工作; CAS Client 负责处理对客户端受保护资源的访问请求,需要登
录时,重定向到 CAS Server。
1. 访问服务: SSO 客户端发送请求访问应用系统提供的服务资源。
2. 定向认证: SSO 客户端会重定向用户请求到 SSO 服务器。
3. 用户认证:用户身份认证。
4. 发放票据: SSO 服务器会产生一个随机的 Service Ticket。
5. 验证票据: SSO 服务器验证票据 Service Ticket 的合法性,验证通过后,允许客户端访问服务。
6. 传输用户信息: SSO 服务器验证票据通过后,传输用户认证结果信息给客户端
CAS 服务端部署
Cas 服务端其实就是一个 war 包。
放入 tomcat 目录下的 webapps 下。启动
tomcat 自动解压 war 包。浏览器输入 http://localhost:8080/cas/login ,可看到登录页面
固定的用户名和密码 casuser /Mellon
登录成功后会跳到登录成功的提示页面
CAS 服务端配置
端口配置
(1) 修改 TOMCAT 的端口
打开 tomcat 目录 conf\server.xml
<connector port=”8080″ protocol=”http/1.1″ ……/>
(2) 修改 CAS 配置文件
修改 cas 的 WEB-INF/cas.properties
server.name=http://localhost:9100 |
去除 https 认证
(1) 修改 cas 的 WEB-INF/deployerConfigContext.xm
<bean class=”org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationH andler” p:httpClient-ref=”httpClient”/> |
这里需要增加参数 p:requireSecure=”false”, requireSecure 属性意思为是否需要安全验证,即
HTTPS, false 为不采用
(2) 修改 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” /> |
参数 p:cookieSecure=”true”,同理为 HTTPS 验证相关, TRUE 为采用 HTTPS 验证, FALSE 为不
采用 https 验证。
参数 p:cookieMaxAge=”-1″,是 COOKIE 的最大生命周期, -1 为无生命周期,即只在当前打开
的窗口有效,关闭或重新打开其它窗口,仍会要求验证。可以根据需要修改为大于 0 的数字,
比如 3600 等,意思是在 3600 秒内,打开任意窗口,都不需要验证。
我们这里将 cookieSecure 改为 false , cookieMaxAge 改为 3600
(3)修改 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” /> |
我们这里将 cookieSecure 改为 false , cookieMaxAge 改为 3600
登出跳转的配置
修改 cas 系统的配置文件 cas-servlet.xml
<bean id=”logoutAction” class=”org.jasig.cas.web.flow.LogoutAction” p:servicesManager-ref=”servicesManager” p:followServiceRedirects=”${cas.logout.followServiceRedirects:true}”/> |
改为 true 后,可以在退出时跳转页面到目标页面,修改 index.jsp 的退出链接
<a href=”http://localhost:9100/cas/logout?service=http://www.baidu.com”>退出登录</a> |
CAS 服务端数据源设置
实现用户名和密码从自己的数据库中匹配
修改 cas 服务端中 web-inf 下 deployerConfigContext.xml ,添加如下配置
<bean id=”dataSource” class=”com.mchange.v2.c3p0.ComboPooledDataSource”
(2)将以下三个 jar 包放入 webapps\cas\WEB-INF\lib 下 |
CAS 服务端界面改造
(1)将自己的登陆页 login.html 拷贝到 cas 系统下 WEB-INF\view\jsp\default\ui 目录下
(2)将 css js 等文件夹拷贝到 cas 目录下
(3) 将原来的 casLoginView.jsp 改名(可以为之后的修改操作做参照),将 login.html 改名为 casLoginView.jsp
CAS 客户端与 SpringSecurity 集成
大概都在这个文件的过滤器了吧
<!– 一,不需要权限认证的静态资源需要放行 –>
<http pattern=”/css/**” security=”none”></http>
<http pattern=”/js/**” security=”none”></http>
<http pattern=”/fonts/**” security=”none”></http>
<http pattern=”/data/**” security=”none”></http>
<http pattern=”/img/**” security=”none”></http>
<http pattern=”/plugins/**” security=”none”></http>
<http pattern=”/register.html” security=”none”></http>
<http pattern=”/user/createSmsCode” security=”none”></http>
<http pattern=”/user/register” 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.66.66:9000/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:8084/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.66.66:9000/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.pyg.user.service.impl.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.66.66:9000/cas/logout?service=http://localhost:8084″ />
<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>