CAS 介绍
CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点:
- 开源的企业级单点登录解决方案。
- CAS Server 为需要独立部署的 Web 应用。
- CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。
CAS 原理和协议
从结构上看,CAS 包含两个部分: CAS Server 和 CAS Client。CAS Server 需要独立部署,主要负责对用户的认证工作;CAS Client 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 CAS Server。图1 是 CAS 最基本的协议过程:
图 1. CAS 基础协议
![单点登录----->cas实现单点登录 单点登录----->cas实现单点登录](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9hSFIwY0RvdkwzZDNkeTVwWW0wdVkyOXRMMlJsZG1Wc2IzQmxjbmR2Y210ekwyTnVMMjl3Wlc1emIzVnlZMlV2YjNNdFkyNHRZMkZ6TDJsdFlXZGxjeTlwYldGblpUQXdNUzVxY0djPQ%3D%3D.jpg?w=700&webp=1)
CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。对于访问受保护资源的每个 Web 请求,CAS Client 会分析该请求的 Http 请求中是否包含 Service Ticket,如果没有,则说明当前用户尚未登录,于是将请求重定向到指定好的 CAS Server 登录地址,并传递 Service (也就是要访问的目的资源地址),以便登录成功过后转回该地址。用户在第 3 步中输入认证信息,如果登录成功,CAS Server 随机产生一个相当长度、唯一、不可伪造的 Service Ticket,并缓存以待将来验证,之后系统自动重定向到 Service 所在地址,并为客户端浏览器设置一个 Ticket Granted Cookie(TGC),CAS Client 在拿到 Service 和新产生的 Ticket 过后,在第 5,6 步中与 CAS Server 进行身份合适,以确保 Service Ticket 的合法性。
在该协议中,所有与 CAS 的交互均采用 SSL 协议,确保,ST 和 TGC 的安全性。协议工作过程中会有 2 次重定向的过程,但是 CAS Client 与 CAS Server 之间进行 Ticket 验证的过程对于用户是透明的。
另外,CAS 协议中还提供了 Proxy (代理)模式,以适应更加高级、复杂的应用场景,具体介绍可以参考 CAS 官方网站上的相关文档。
准备工作
本文中的例子以 tomcat7为例进行讲解,下载地址:
到 CAS 官方网站下载 CAS Server 和 Client,地址分别为:
http://www.ja-sig.org/downloads/cas/cas-server-3.1.1-release.zip
http://www.ja-sig.org/downloads/cas-clients/cas-client-java-2.1.1.zip
配置casServer
1.新建web项目
2、将cas-server.war文件中的文件放到Eclipse web项目的相关目录下:
![单点登录----->cas实现单点登录 单点登录----->cas实现单点登录](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9hSFIwY0RvdkwybHRaeTVpYkc5bkxtTnpaRzR1Ym1WMEx6SXdNVFV4TURFeU1UTXpOVFV6TWpZeFAzZGhkR1Z5YldGeWF5OHlMM1JsZUhRdllVaFNNR05FYjNaTU1rcHpZakpqZFZrelRtdGlhVFYxV2xoUmRpOW1iMjUwTHpWaE5rdzFUREpVTDJadmJuUnphWHBsTHpRd01DOW1hV3hzTDBrd1NrSlJhMFpEVFVFOVBTOWthWE56YjJ4MlpTODNNQzluY21GMmFYUjVMME5sYm5SbGNnPT0%3D.jpg?w=700&webp=1)
3、设置虚拟目录
通过<Context/>形式指定Eclipse下的项目为项目的根目录,建立好三个虚拟目录,如下:在host中做映射
.......................
4、建立客户端项目-两个
项目中使用了jstl.jar包,应该放到WEB-INF/lib目录下。
第5步:先测试服务器是否可以正常使用
启动tomcat,在地址栏输入:
第6步:修改客户端的配置文件
当使用登录客户端受保护的资源时,如果发现还没有登录,则会重定向到服务器(售票处)请求登录验证,登录成功后即会获取一张票据,服务器会携带这张票据再重定向到客户端页面。
修改客户端的web.xml配置文件,让它在登录时,知道去哪台服务器:
注意将里面的https全部修改成http。
修改的部分主要分为两块:
1:修改登录重定向过虑器,它用于保护受保护的资源,如果发面用户在访问受保护的资源时,用户还没有登录,则会重定向到服务器,要求用户登录:
![单点登录----->cas实现单点登录 单点登录----->cas实现单点登录](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9hSFIwY0RvdkwybHRaeTVpYkc5bkxtTnpaRzR1Ym1WMEx6SXdNVFV4TURFeU1UTTBNVE15TXprMVAzZGhkR1Z5YldGeWF5OHlMM1JsZUhRdllVaFNNR05FYjNaTU1rcHpZakpqZFZrelRtdGlhVFYxV2xoUmRpOW1iMjUwTHpWaE5rdzFUREpVTDJadmJuUnphWHBsTHpRd01DOW1hV3hzTDBrd1NrSlJhMFpEVFVFOVBTOWthWE56YjJ4MlpTODNNQzluY21GMmFYUjVMME5sYm5SbGNnPT0%3D.jpg?w=700&webp=1)
另一个也是如此的配置
2、修改验证过虑器,它的主要作用是接收服务器发送的Ticket,进行验证
其他没有说明的部分,请不要修改。
请参考上面的实现配置另一个项目的web.xml文件。
第7步:测试登录
目前还不能实现单点登录。但可以对任意的一个客户端进行登录验证。
1、 在地址栏输入
点击访问受保护的页面:got to protected area
将重定向到服务器请求登录:
第8步:配置可以单点登录
Cas服务器都是用spring配置文件配置而成。且使用了cookie技术。在ticketGrantingTicketCookieGenerator.xml文件中,保存了cookie的生成方式及有效时间注意,这是在server服务器上的spring配置文件。
打开此文件,修改成以下内容:
![单点登录----->cas实现单点登录 单点登录----->cas实现单点登录](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9hSFIwY0RvdkwybHRaeTVpYkc5bkxtTnpaRzR1Ym1WMEx6SXdNVFV4TURFeU1UTTBOVFV3T0RJMFAzZGhkR1Z5YldGeWF5OHlMM1JsZUhRdllVaFNNR05FYjNaTU1rcHpZakpqZFZrelRtdGlhVFYxV2xoUmRpOW1iMjUwTHpWaE5rdzFUREpVTDJadmJuUnphWHBsTHpRd01DOW1hV3hzTDBrd1NrSlJhMFpEVFVFOVBTOWthWE56YjJ4MlpTODNNQzluY21GMmFYUjVMME5sYm5SbGNnPT0%3D.jpg?w=700&webp=1)
这就简单集成了cas
修改服务器的登录验证规则
修改配置文件:/WEB-INF/deployerConfigContext.xml。 -
在<property name= "authenticationHandlers">...属性内部,通过配置若干的AuthenticationHandler的子类,可以改变登录认证方式。也可以增加认证方式,只要在用户登录时,有一种登录方式是可行的,即可以登录成功。
默认已经配置了最后一个类即SimpleTestUsernamePasswordAuthenticationHandler。此类验证用户名和密码是否一致。
Cas为我们提供了可以直接配置用户名和密码类:即org.jasig.cas.adaptors.generic.AcceptUsersAuthenticationHandler。此类并没有包含到默认的服务器代码中,需要到cas-server/models/中查找名为:cas-server-support-generic-3.4.11.jar的jar文件,并添加到WEB-INF/lib目录下。
如下图所示,正是名为generic的jar包。(后面如果需要数据库连接的,还需要jdbc的jar包)
需要的包:
在/WEB-INF/deployerConfigContext.xml配置文件中的<property name= "authenticationHandlers">元素中,删除原来的用户名与密码相同的认证,即:
如果使用自己编写的类来验证登录用户名和密码:则要继承AbstractUsernamePasswordAuthenticationHandler
7、配置使用JDBC的登录 ,认证句柄: AuthenticationHandler
在<property name= "authenticationHandlers">...属性内部,通过配置若干的AuthenticationHandler的子类,可以改变登录认证方式。也可以增加认证方式,只要在用户登录时,有一种登录方式是可行的,即可以登录成功。
所有的配置方式,在CAS的官方网站上均有详细的说明。
修改配置文件:/WEB-INF/deployerConfigContext.xml。
在这个配置文件中,保存了多个用户认证登录的验证方式,只要有一种验证通过即可以登录成功。
以下是在配置文件中增加用户名和密码的登录的方式,其中设置了MD5对密码进行加密。默认的加密方式为PlainTextPasswordEncoder.即不加密。
1、使用数据库指定表名,字段名的登录认证方式
A:创建数据库:
createdatabase ssocharacterset UTF8;
use sso;
createtable users(
id varchar(32),
namevarchar(30),
pwd varchar(32)
);
insertinto usersvalues('U001','Jack','1234');
insertinto usersvalues('U002','Rose','4321');
B:在/WEB-INF/deployerConfigContext.xml文件的最下面,创建数据连接:
<beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<propertyname="driverClassName"value="com.mysql.jdbc.Driver"/>
<propertyname="url"value="jdbc:mysql:///sso?characterEncoding=UTF-8"/>
<propertyname="username"value="root"/>
<propertyname="password"value="1234"/>
</bean>
C:使用dataSource数据源,因为后面的查询需要一个数据源的支持:
<!-- 使用数据库验证,且数据库的密码是经过md5加密的 -->
<beanclass="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler">
<propertyname="dataSource"ref="dataSource"/>
<propertyname="tableUsers"value="users"/>
<propertyname="fieldUser"value="name"/>
<propertyname="fieldPassword"value="pwd"/>
<propertyname="passwordEncoder"> <!--可选的加密-->
<beanclass="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
<constructor-argvalue="MD5"/>
<propertyname="characterEncoding"value="UTF-8"></property>
</bean>
</property>
</bean>
MySql的表结构如下:
2、使用查询sql验证用户登录的方式
<!-- 使用sql语句 -->
<beanclass="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<propertyname="dataSource"ref="dataSource"/>
<propertyname="sql"value="select pwd fromusers where name=?"/>
<propertyname="passwordEncoder">
<beanclass="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
<constructor-argvalue="MD5"/>
<property name="characterEncoding"value="UTF-8"></property>
</bean>
</property>
</bean>