CAS原理与配置-基于CAS的单点登陆的研究(上)

1     前言

 

单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架,本文介绍了 CAS 的原理、协议、在 Tomcat 中的配置和使用,研究如何采用 CAS 实现轻量级单点登录解决方案。

CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点:

开源的企业级单点登录解决方案。

CAS Server 为需要独立部署的 Web 应用。

CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。

 2     CAS的原理

 2.1               从结构体系看, CAS 包含两部分

CAS Server

CAS Server 负责完成对用户的认证工作, CAS Server 需要独立部署,有不止一种 CAS Server 的实现, Yale CAS Server 和 ESUP CAS Server 都是很不错的选择。

CAS Server 会处理用户名 / 密码等凭证 (Credentials) ,它可能会到数据库检索一条用户帐号信息,也可能在 XML 文件中检索用户密码,对这种方式, CAS 均提供一种灵活但同一的接口 / 实现分离的方式, CAS 究竟是用何种认证方式,跟 CAS 协议是分离的,也就是,这个认证的实现细节可以自己定制和扩展。

CAS Client

CAS Client 负责部署在客户端(注意,我是指 Web 应用),原则上, CAS Client 的部署意味着,当有对本地 Web 应用的受保护资源的访问请求,并且需要对请求方进行身份认证, Web 应用不再接受任何的用户名密码等类似的 Credentials ,而是重定向到 CAS Server 进行认证。

目前, CAS Client 支持(某些在完善中)非常多的客户端,包括 Java 、 .Net 、 ISAPI 、 Php 、 Perl 、 uPortal 、 Acegi 、 Ruby 、 VBScript 等客户端,几乎可以这样说, CAS 协议能够适合任何语言编写的客户端应用。

 2.2               协议

从CAS v1到现在的CAS v3,整个协议的基础思想都是基于票据方式。

 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的方法上虽然有所区别,但是,最终都可以实现这样一个目的——免去多次登录的麻烦。 

TGT + S = ST ?(可能是这样)

下面,我们看看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 ,直接访问 clientweb 应用,它被立即重定向到 CAS Server 进行认证, User 可能感觉到浏览器在 clientweb 和 casserver 之间重定向,但 User 是看不到, CAS Client 和 CAS Server 相互间的 Service Ticket 核实 (Validation) 过程。当 CAS Server 告知 CAS Client 用户 Service Ticket 对应确凿身份, CAS Client 才会对当前 Request 的用户进行服务。

再看两个比较有用的图,这个是从网上找到的,一个是CAS浏览器请求序列图,另一个是CAS服务器端登陆流程图(参考http://hi.baidu.com/dianjinglong/blog/item/f74f353156d390a15fdf0e43.html)

 

                                       CAS浏览器请求序列图

 

                                        CAS服务器端登陆流程图

 3     CAS Server端配置

Server端主要是需要安装Server的WAR包,并运行起来。由于 Client 与 CAS Server 之间的交互采用 Https 协议,因此部署 CAS Server 的服务器还需要支持 SSL 协议。当 SSL 配置成功过后,(也可以不使用SSL协议,而使用普通方式)像普通 Web 应用一样将 CAS Server 部署在服务器上就能正常运行了,不过,在真正使用之前,还需要扩展验证用户的接口。

 3.1               增加tomcat的SSL配置

生成key的步骤省略,参看这里,介绍的很详细。之后配置tomcat的server.xml文件,增加如下配置,将JDK的cacerts配置到tomcat的信任库中:

修改%TOMCAT_HOME%/conf/server.xml

去掉下面SSL HTTP那个注释,修改为如下: 

Xml代码

<Connector port="8443" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"    

   SSLEnabled="true"  

   maxThreads="150"  

   scheme="https"  

   secure="true"  

   clientAuth="false"  

   sslProtocol="TLS"    

   keystoreFile="/conf/tomcat.keystore"  

 keystorePass="123456" />

 keystoreFile 是tomcat.keystore放置的位置,keystorePass是前面生成tomcat.keystore所设置的密码(123456)

 

     也可取消CAS的HTTPS登录,需要设置几个地方。可以参考这里。

概括来说就是查找Secure字符,找到两个设置的地方,把true改成false;

修改deployerConfigContext.xml 

<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"      p:httpClient-ref="httpClient" />  

添加p:requireSecure="false"

客户端可能也需要进行修改。

 

 3.2     扩展认证接口

    我这里的Cas-server的版本是 3.4.2.1

目前,部署下载的server中module里的war包到tomcat中,启动tomcat,然后访问:https://localhost:8443/cas ,如果能出现正常的 CAS 登录页面,则说明 CAS Server 已经部署成功。

虽然 CAS Server 已经部署成功,但这只是一个缺省的实现,在默认的server界面,只要输入用户名和密码相同,就可以登录。当然,在实际使用的时候,这样做肯定是不行的,还需要根据实际概况做扩展和定制,最主要的是扩展认证 (Authentication) 接口和 CAS Server 的界面。

我们通常都会使用jdbc连接数据库进行认证,这种情况,用户名和密码被保存在数据库的某个表中。需要进行如下配置。

 3.2.1         配置jdbc sql语句认证方式

用编辑器打开/webapps/cas-server-3.1.1/WEB-INF/deployerConfigContext.xml,找到如下xml,并注释掉该代码:

<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsername

PasswordAuthenticationHandler" />

在下面填写如下代码:

<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">

<property name="sql" value="select password from usertable where username=?" />

    <property name="dataSource" ref="dataSource" />

</bean>

并添加一个bean:

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">

       <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>

       <property name="url"><value>jdbc:mysql://localhost:3306/test</value></property>

       <property name="username"><value>test</value></property>

       <property name="password"><value>test</value></property>

</bean>

假设使用数据库密码sd5加密,则增加配置如下:(红色部分是sd5加密配置)

<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">  

<property name="sql" value="select password from usertable where username=?" />  

<property name="passwordEncoder" ref="passwordEncoder"/>  

 <property name="dataSource" ref="dataSource" />  

</bean>

<bean id="passwordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder" autowire="byName">

<constructor-arg value="MD5"/>

</bean>

注意,再次部署,还需要增加几个包,做为依赖,如果使用maven,可以加入如下代码:

       <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

            <version>5.1.12</version>

        </dependency>

        <dependency>

            <groupId>org.apache.openejb</groupId>

            <artifactId>commons-dbcp-all</artifactId>

            <version>1.3-r699049</version>

        </dependency>

 如果您不使用maven管理的话,可以下载相应的包,并拷贝到WEB-INF/lib/中,重新启动tomcat即可。

 

创建表 

mysql> create table user(id int,username char(100) NOT NULL,password char(100) NOT NULL,PRIMARY KEY (id));

mysql> insert into user values(2,'admin','admin123');

 

 3.3               RESTFul 配置

CAS提供了 RestFul API ,Restlet配置如下:

        <dependency>

            <groupId>org.jasig.cas</groupId>

            <artifactId>cas-server-integration-restlet</artifactId>

            <version>3.4.11</version>

            <type>jar</type>

        </dependency>

 然后再在 web.xml 中加入:

 <servlet>

        <servlet-name>restlet</servlet-name>

        <servlet-class>com.noelios.restlet.ext.spring.RestletFrameworkServlet</servlet-class>

        <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

        <servlet-name>restlet</servlet-name>

        <url-pattern>/v1/*</url-pattern>

    </servlet-mapping>

地址:http://IP:8080/cas/v1/tickets

 

 3.4              SPRING security 集成

Spring security  3.1.x的首页讲了如何配置它到您的项目,在线官方文档请点击这里;跟CAS相关的章节请点击这里。3.0.X的SPRING官方也有讲解,再这里,讲的没有3.1.X的内容多。

CAS官方网站也给了个例子,用于于Spring security集成,不过讲的也不是很详细,可以点击这里查看。

国内的找了两篇写的可以的,点击 链接1,链接2 来查看。

 

 

 3.5 关于登出

可以参考这里。

 3.6 登录验证之添加“用户不存在”错误信息

参考这里。

以上都是Server端的配置,下一篇将会总结客户端的配置。

 

4.问题

4.1证书的问题

在打证书的时候,输入了

您的名字与姓氏是什么?

 经测试发现..如果caserver与单点服务在同一台电脑上,用key里注册的localhost访问是不会有问题的.但是如果不在同一台电脑上..内网访问也会出错!

所以这里不主张用localhost,可以用ip注册,内网访问用ip将不会有问题.(可是实际上CAS中也是不主张用IP来注册的)

   另一个域名,将localhost改写成caserver单点所在服务器上的计算机名(右击我的电脑,属性,计算机名).测试通过!(这种方式虽然没有问题,但是必须把部署的机器名称改为此认证中的名称,比如master)

4.2 客户端只能使用域名来对中心发出申请,而不能使用IP。

你可能感兴趣的:(单点登录)