CAS(Central Authentication Service) 是 Yale 大学发起的一个开源项目。
从结构体系看, CAS 包含两部分:
l CAS Server
CAS Server 负责完成对用户的认证工作, CAS Server 需要独立部署,有不止一种 CAS Server 的实现, Yale CAS Server 和 ESUP CAS Server 都是很不错的选择。
CAS Server 会处理用户名 / 密码等凭证 (Credentials) ,它可能会到数据库检索一条用户帐号信息,也可能在 XML 文件中检索用户密码,对这种方式, CAS 均提供一种灵活但同一的接口 / 实现分离的方式, CAS 究竟是用何种认证方式,跟 CAS 协议是分离的,也就是,这个认证的实现细节可以自己定制和扩展。
l CAS Client
CAS Client 负责部署在客户端(注意,我是指 Web 应用),原则上, CAS Client 的部署意味着,当有对本地 Web 应用的受保护资源的访问请求,并且需要对请求方进行身份认证, Web 应用不再接受任何的用户名密码等类似的 Credentials ,而是重定向到 CAS Server 进行认证。
目前, CAS Client 支持(某些在完善中)非常多的客户端,包括 Java 、 .Net 、 ISAPI 、 Php 、 Perl 、 uPortal 、 Acegi 、 Ruby 、 VBScript 等客户端,几乎可以这样说, CAS 协议能够适合任何语言编写的客户端应用。
CAS v1 非常原始,传送一个用户名居然是 ”yes/ndavid.turing” 的方式, CAS v2 开始使用了 XML 规范,大大增强了可扩展性, CAS v3 开始使用 AOP 技术,让 Spring 爱好者可以轻松配置 CAS Server 到现有的应用环境中。
CAS 是通过 TGT(Ticket Granting Ticket) 来获取 ST(Service Ticket) ,通过 ST 来访问服务,而 CAS 也有对应 TGT , ST 的实体,而且他们在保护 TGT 的方法上虽然有所区别,但是,最终都可以实现这样一个目的——免去多次登录的麻烦。
下面,我们看看 CAS 的基本协议框架:
基础协议
CAS 基础模式
上图是一个最基础的 CAS 协议, CAS Client 以 Filter 方式保护 Web 应用的受保护资源,过滤从客户端过来的每一个 Web 请求,同时, CAS Client 会分析 HTTP 请求中是否包请求 Service Ticket( 上图中的 Ticket) ,如果没有,则说明该用户是没有经过认证的,于是, CAS Client 会重定向用户请求到 CAS Server ( Step 2 )。 Step 3 是用户认证过程,如果用户提供了正确的 Credentials , CAS Server 会产生一个随机的 Service Ticket ,然后,缓存该 Ticket ,并且重定向用户到 CAS Client (附带刚才产生的 Service Ticket ), Service Ticket 是不可以伪造的,最后, Step 5 和 Step6 是 CAS Client 和 CAS Server 之间完成了一个对用户的身份核实,用 Ticket 查到 Username ,因为 Ticket 是 CAS Server 产生的,因此,所以 CAS Server 的判断是毋庸置疑的。
该协议完成了一个很简单的任务,就是 User(david.turing) 打开 IE ,直接访问 helloservice 应用,它被立即重定向到 CAS Server 进行认证, User 可能感觉到浏览器在 helloservcie 和 casserver 之间重定向,但 User 是看不到, CAS Client 和 CAS Server 相互间的 Service Ticket 核实 (Validation) 过程。当 CAS Server 告知 CAS Client 用户 Service Ticket 对应确凿身份, CAS Client 才会对当前 Request 的用户进行服务。
CAS 可以很简单的实现跨域的 SSO ,因为,单点被控制在 CAS Server ,用户最有价值的 TGC-Cookie 只是跟 CAS Server 相关, CAS Server 就只有一个,因此,解决了 cookies 不能跨域的问题。
回到 CAS 的基础协议图,当 Step3 完成之后, CAS Server 会向 User 发送一个 Ticket granting cookie (TGC) 给 User 的浏览器,这个 Cookie 就类似 Kerberos 的 TGT ,下次当用户被 Helloservice2 重定向到 CAS Server 的时候, CAS Server 会主动 Get 到这个 TGC cookie ,然后做下面的事情:
如果 User 的持有 TGC 且其还没失效,那么就走基础协议图的 Step4 ,达到了 SSO
简单示例
此示例CAS服务器与CAS客户端使用相同的Tomcat
1 配置WEB服务器的HTTPS服务
1.1 开启Tomcat的HTTPS服务
环境:Windows XP + JDK 1.6 + apache-tomcat-5.5.23
1) 生成服务器端密钥并保存到密钥库文件中
- %JAVA_HOME%/bin/keytool -genkey -alias tomcat -keyalg RSA -keystore keystore.jks
-alias 自定义别名,此处取tomcat;
-keyalg 主要两种方式:RSA采用MD5加RSA算法加密密钥,DSA 采用SHA1加DSA算法加密密钥,此处采用RSA;
-keystore 密钥库文件。
注意:当用户输入keystore.jks文件的保护密码后(与JVM信任库密码一致:changeit),系统提示“您的名字与姓氏是什么”时,此时应输入本机的域名,如shazhenzhong或shazhenzhong,在此我们输入shazhenzhong,最后就用https://shazhenzhong:8443来测试配置是否成功。域名配置参见:C:/WINDOWS/system32/drivers/etc下的Hosts文件(增加一个本地名描述127.0.0.1 shazhenzhong)。
如果客户端应用与CAS server不在同一JVM中,请执行2)和3):
2) 导出服务端证书
- %JAVA_HOME%/bin/keytool -export -file myserver.cert -alias tomcat -keystore keystore.jks
由keystore.jks文件中的tomcat别名项导出myserver.cert服务端证书。
3) 将服务端证书导入JVM信任库中
keytool -import -trustcacerts -alias tomcat -file myserver.cert -keystore C:/"Program Files"/Java/jdk1.6.0_10/jre/lib/security/cacerts
将服务端证书myserver.cert以别名tomcat导入JVM的信任库中,JVM信任库文件cacerts的默认密码为changeit。
注:删除与查看客户端证书,在证书误操作后可以调整
- keytool -delete -alias tomcat -keystore C:/"Program Files"/Java/jdk1.6.0_10/jre/lib/security/cacerts
- keytool -list -keystore C:/"Program Files"/Java/jdk1.6.0_10/jre/lib/security/cacerts >t.txt
4) 配置Tomcat的SSL项
把最初生成的keystore.jks复制到%TOMCAT_HOME%/conf下。
找到%TOMCAT_HOME%/conf/server.xml文件,解开SSL的注释。
实例配置如下:
- <Connector port="8443"
- maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
- enableLookups="false" disableUploadTimeout="true"
- acceptCount="100" debug="0" scheme="https" secure="true"
- clientAuth="false" sslProtocol="TLS"
- keystoreFile="conf/keystore.jks"
- keystorePass="changeit"/>
此处主要更改keystoreFile和keystorePass属性项,keystoreFile为1)中所生成的文件,
5) 测试
启动Tomcat,输入https://shazhenzhong:8443,如能正常访问配置就完成了,此处的shazhenzhong是第1)步中输入的“您的名字与姓氏是什么”。
1.2 部署CAS Server应用
下载cas-server-3.1.1及Yale Java Client 2.1.1,在解压的server包中找到cas-server-3.1.1/modules/cas-server-webapp-3.1.1.war 改名为cas.war,直接COPY到WEB服务器的部署目录即可。
1.3 在应用中加入Yale Java Client配置
这里的“应用”,可以说成是CAS里常说的客户端,此次使用apache-tomcat-5.5.23/webapps/servlets-examples。
1)在Yale Java Client解压目录中找到cas-client-java-2.1.1/dis/casclient.jar与servlet.jar,将其COPY到应用中的WEB-INF/lib包下。
2)在应用部署描述文件WEB-INF/web.xml中加入
- <filter>
- <filter-name>CASFilter</filter-name>
- <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
- <init-param>
- <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
- <param-value>https://shazhenzhong:8443/cas/login</param-value>
- </init-param>
- <init-param>
- <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
- <param-value>https://shazhenzhong:8443/cas/proxyValidate</param-value>
- </init-param>
- <init-param>
- <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
- <param-value>shazhenzhong:8080</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>CASFilter</filter-name>
- <url-pattern>/* </url-pattern>
- </filter-mapping>
参数解释:
edu.yale.its.tp.cas.client.filter.loginUrl 用户未登录情况下,访问应用系统的受保护资源时将会跳转到的登录页面URL,这里的值即是对应于部署的Yale CAS Server的登录页。
edu.yale.its.tp.cas.client.filter.validateUrl 用来校验ST(Service Ticket)。
edu.yale.its.tp.cas.client.filter.serverName 客户端的访问时的主机地址。
3) 启动Tomcat,当访问客户端受保护资源时,CASFilter将访问重定向到CAS Server进行登录,输入用户名和密码(用户名和密码相同即可)。若登录成功,CAS Server 将访问又重定向回原客户端。