原文链接
译文
32.CAS鉴权
32.1 概述
JA-SIG 搞了一个 企业范围内的单点登录系统:就是闻名天下的CAS。跟其他替代品不一样的地方在于,JA-SIG的中心鉴权服务是开源的,被广泛是用的,容易理解的,独立于平台的,支持代理能力的。Spring的安全模块完全支持CAS,并提供了比较容易的迁移方案,从单应用部署(Spring Security)到多应用部署(企业层CAS server)
可以从这个网址了解CAS。你也需要访问这个网址来下载CAS服务器文件。
32.2 CAS是怎么工作的呢?
尽管官网提供了CAS架构的细节,我们还是在Spring Security的上下文语境下再来亿遍。Spring Security 3.x 支持 CAS 3。
在你的企业内部某个地方你需要搞一个CAS server。CAS server就是一个简单的标准的WAR文件,所以安装配置这个server肯定是没啥困难的。在WAR文件里你会自定义一些展示给用户的单点登录页面。
当我们部署CAS3.4服务器,你会需要在deployerConfigContext.xml
指定AuthenticationHandler
。这个AuthenticationHandler
有一个简单的方法,返回boolean,说明这个证书是否有效。你的AuthenticationHandler
实现需要连接某种后端存储,比如LDAP服务器或者数据库。CAS本身包含了好几种AuthenticationHandler
,开箱即用。当你下载并部署服务器war文件,他就已经成功设定好了,匹配用户名和密码。
除了CAS服务器本身,其他关键的玩家,当然是安全web应用。这些web应用就是”服务“。有三种类型的服务。那些验证服务ticket的、那些获取代理ticket的、那些校验代理ticket的。校验代理ticket会不一样,因为一堆代理必须被校验,而且经常代理ticket可以复用。
32.2.1 Spring Security和 CAS交互顺序
web server、CAS server、Spring安全服务的基本的交互如下:
- 用户浏览服务的公告页面,不涉及CAS或者Spring Security
- 用户访问了一个安全相关的页面。Spring Security的
ExceptionTranslationFilter
会 检测到AccessDeniedException
或者AuthenticationException
- 因为用户的
Authentication
引发了AuthenticationException
,ExceptionTranslationFilter
会调用配置好的AuthenticationEntryPoint
。如果使用CAS,就会是这个类:CasAuthenticationEntryPoint
CasAuthenticationEntryPoint
会重定向用户的浏览器到CAS服务器,指定一个参数:service
,也就是回调url(指向原来要访问的应用)。比如: https://my.company.com/cas/login?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Flogin/cas.- 用户浏览器重定向到CAS,输入用户名和密码,如果用户有一个session cookie指明他们之前已经登陆了,他们就不需要再登陆了。CAS会使用PasswordHandler(如果是CAS3.0的话则是AuthenticationHandler),校验用户名和密码
- 如果成功登陆了,CAS重定向用户的浏览器到原来的服务。这里面还会有一个ticket参数,举个例子:https://server3.company.com/webapp/login/cas?ticket=ST-0-ER94xMJmn6pha35CQRoZ.
- 回到我们的服务,
CasAuthenticationFilter
会一直监听login/cas
的请求。这个filter会构造UsernamePasswordAuthentictionToken
,代表服务ticket。 - 省略一些中间步骤。。。。。。。。
TicketValidator
发起HTTPs请求给CAS服务器,校验服务ticket。举例:https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Flogin/cas&ticket=ST-0-ER94xMJmn6pha35CQRoZ&pgtUrl=https://server3.company.com/webapp/login/cas/proxyreceptor.- 回到CAS server,校验ticket。
- 最后重定向回到原来访问的页面
32.3 CAS客户端的配置
32.3.1 服务ticket 校验
添加一个ServiceProperties bean,指定CAS 服务
<bean id="serviceProperties"
class="org.springframework.security.cas.ServiceProperties">
<property name="service"
value="https://localhost:8443/cas-sample/login/cas"/>
<property name="sendRenew" value="false"/>
</bean>
再加上以下的beans
<security:http entry-point-ref="casEntryPoint">
...
<security:custom-filter position="CAS_FILTER" ref="casFilter" />
</security:http>
<bean id="casFilter"
class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<bean id="casEntryPoint"
class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl" value="https://localhost:9443/cas/login"/>
<property name="serviceProperties" ref="serviceProperties"/>
</bean>
配置CASAuthenticationProvider和他的合作者
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="casAuthenticationProvider" />
</security:authentication-manager>
<bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<property name="authenticationUserDetailsService">
<bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<constructor-arg ref="userService" />
</bean>
</property>
<property name="serviceProperties" ref="serviceProperties" />
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="https://localhost:9443/cas" />
</bean>
</property>
<property name="key" value="an_id_for_this_auth_provider_only"/>
</bean>
<security:user-service id="userService">
<security:user name="joe" password="joe" authorities="ROLE_USER" />
...
</security:user-service>
以上就是CAS的最基础的配置。如果没啥事务,你的应用程序就可以开心地跑起来了。