SSO单点登录Spring-Security & CAS使用手册

时间:2024-04-20 20:38:03

1.1概述

1.1.1单点登录介绍

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

本文介绍了 CAS 的原理、协议、以及配合Spring-Security在 Tomcat 中的配置和使用。

1.1.2 CAS 、Spring Security介绍

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

  • 开源的企业级单点登录解决方案。
  • CAS Server 为需要独立部署的 Web 应用。
  • CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。

Spring Security为基于J2EE企业应用软件提供了全面安全服务。Spring Security广泛支持各种身份验证模式。 这些验证模型绝大多数都由第三方提供,或正在开发的有关标准机构提供的,例如Internet Engineering Task Force。 作为补充,Spring Security也提供了自己的一套验证功能。

1.1.3 CAS 原理和协议

从结构上看,CAS 包含两个部分: CAS Server 和 CAS Client。CAS Server 需要独立部署,主要负责对用户的认证工作;CAS Client 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 CAS Server。图1 是 CAS 最基本的协议过程:

图 1. CAS 基础协议

SSO单点登录Spring-Security & CAS使用手册

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 官方网站上的相关文档。

1.2 术语定义

SSO : 单点登录(Single Sign On , 简称 SSO )

CAS : CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架

认证 : 是为用户建立一个他所声明的主体。 主体一般是指用户,设备或可以在你系统中执行行动的其他系统。

授权 : 指的一个用户能否在你的应用中执行某个操作。 在到达授权判断之前,身份的主体已经由身份验证过程建立了。

认证和授权是通用的,不是Spring Security特有的。

1.3 参考资料

http://www.ja-sig.org/products/cas/

http://www.ja-sig.org/wiki/display/CASUM/Home

http://static.springframework.org/spring-security/site/index.html

http://family168.com/tutorial/springsecurity/html/springsecurity.html

--------------------------------------------------------------------------------------------------------

http://www.cnblogs.com/vhua/p/cas_1.html

http://blog.****.net/small_love/article/details/6664831

http://steven-wiki.readthedocs.io/en/latest/security/cas-tomcat/

http://www.kafeitu.me/sso/2010/11/05/sso-cas-full-course.html

http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/

SSO单点登录Spring-Security & CAS使用手册

2 CAS Server安装部署

2.1准备工作

OS: Centos6

JDK: 1.8.0_11

Web Server: Tomcat-7.0.73

CAS Server: cas-server-4.0.0

下载链接:

http://tomcat.apache.org/download-70.cgi

https://github.com/apereo/cas/releases?after=v4.0.2

http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

2.2开始部署 CAS Server

CAS Server 是一套基于 Java 实现的服务,该服务以一个 Java Web Application 单独部署在与 servlet2.3 兼容的 Web 服务器上,另外,由于 Client 与 CAS Server 之间的交互采用 Https 协议,因此部署 CAS Server 的服务器还需要支持 SSL 协议。当 SSL 配置成功过后,像普通 Web 应用一样将 CAS Server 部署在服务器上就能正常运行了,不过,在真正使用之前,还需要扩展验证用户的接口。

在 Tomcat 上部署一个完整的 CAS Server 主要按照以下几个步骤:

2.2.1 配置 Tomcat 使用 Https 协议

如果希望 Tomcat 支持 Https,主要的工作是配置 SSL 协议,其配置过程和配置方法可以参考 Tomcat 的相关文档。不过在生成证书的过程中,会有需要用到主机名的地方,CAS 建议不要使用 IP 地址,而要使用机器名或域名。

为了实现SSL,一个Web服务必须对每一个接受安全连接的外部接口或者IP地址有一个相关联的证书,数字证书的获取一般从像verisign或者Thawte这样的著名证书颁发机构(Certificate Authority CA)购买证书,或者如果身份验证并不很重要,比如管理员只是希望保证服务器发送和接收的数据是私有的并且不能被连接中的任何窃听者探听到,则可以只是使用自签名的证书,从而省去获取CA证书的时间和成本。此处使用自签名证书作为客户端与服务器端安全通信的凭证。

1. 安装JDK1.8

2. 安装tomcat7

3. 设置环境变量JAVA_HOME

安装完毕,启动Tomcat ,在浏览器上 测试 http://localhost:8080/

SSO单点登录Spring-Security & CAS使用手册

出现上述界面,表明系统tomcat成功搭建。

4. 使用Java Keytool工具为系统生成HTTPS证书,并为系统注册

cd $JAVA_HOME/jre/lib/security/

cd /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-0.b15.el6_8.x86_64/jre/lib/security

SSO单点登录Spring-Security & CAS使用手册

keytool -delete -alias tomcat-cas-server -keystore "cacerts" -storepass changeit

keytool -delete -alias tomcat-cas-server -storepass changeit

SSO单点登录Spring-Security & CAS使用手册

(注释: 清除系统中可能存在的名字为tomcat-cas-server的同名证书,“changeit”是jdk中证书的默认密码,如果系统中无tomcat-cas-server名称的证书,则弹出错误警告信息,不用理会)

keytool -list -keystore "/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-0.b15.el6_8.x86_64/jre/lib/security/cacerts" -storepass changeit

SSO单点登录Spring-Security & CAS使用手册

(注释: 列出系统证书仓库中存在证书名称列表)

keytool -genkey -validity 36000 -keyalg RSA -alias tomcat-cas-server -dname "cn=hello.cas.server" -storepass changeit

cn换成自己的域名

SSO单点登录Spring-Security & CAS使用手册

(注释:如果不指定证书文件的文件名和存放地址,默认位置为用户家目录, 默认文件名 .keystore, 具体参数参见keytool命令。

[-validity <valDays>]为证书有效期,指定使用RSA算法,生成别名为tomcat-cas-server的证书,存贮口令为changeit,也可以保存其他的口令!证书的DN为"cn= test.cas.server ",这个DN必须同当前主机完整名称一致哦,切记!!!)

SSO单点登录Spring-Security & CAS使用手册

keytool -export -alias tomcat-cas-server -file "$JAVA_HOME/jre/lib/security/server.crt" -storepass changeit

$JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-0.b15.el6_8.x86_64/

SSO单点登录Spring-Security & CAS使用手册

(注释: 从keystore中导出别名为tomcat-cas-server的证书,生成文件server.crt)

keytool -import -alias tomcat-cas-server -file "server.crt" -keystore "cacerts" -storepass changeit

SSO单点登录Spring-Security & CAS使用手册

(注释:将server.crt导入jre的可信任证书仓库。注意,安装JDK是有两个jre目录,一个在jdk底下,一个是独立的jre,这里的目录必须同Tomcat使用的jre目录一致,否则后面Tomcat的HTTPS通讯就找不到证书了)

重点:保存该server.crt证书,CAS Client端部署的时候同样需要导入该证书。这样CAS Server和Cas Client才能通过“握手”验证。

keytool -list -keystore "$JAVA_HOME/jre/lib/security/cacerts" -storepass changeit > list.txt

SSO单点登录Spring-Security & CAS使用手册

(注释:列出jre可信任证书仓库中证书名单,验证先前的导入是否成功,如果导入成功,应该在列表中能找到tomcat-cas-server这个别名)

在%JAVA_HOME%\jre\lib\security目录下能找到“server.crt”这个文件;

SSO单点登录Spring-Security & CAS使用手册

在用户家目录目录下能找到“.keystore”文件。

拷贝.keystore到$CATALINA_HOME\conf下。

$CATALINA_HOME=tomcat安装目录

SSO单点登录Spring-Security & CAS使用手册

--------------------------------------------------------------------------------------------------------------

SSO单点登录Spring-Security & CAS使用手册

5. 配置Tomcat的HTTPS服务

编辑%CATALINA_HOME%\conf下的server.xml文件,修改<!-- Define a SSL HTTP/1.1 Connector on port 8443 -->下面的http1.1配置,

<Connector protocol="org.apache.coyote.http11.Http11Protocol"

                        port="8443" minSpareThreads="5" maxSpareThreads="75"

                        enableLookups="true" disableUploadTimeout="true"

                        acceptCount="100" maxThreads="200"

                        scheme="https" secure="true" SSLEnabled="true"

                        keystoreFile="conf/.keystore"

                        keystorePass="changeit"

                        clientAuth="false" sslProtocol="TLS" />

<!-- keystoreFile 指定证书位置,如果不指定默认位置为用户加目录下.keystore -->

<!—keystorePass你生成证书时的口令 -->
<Connector protocol="org.apache.coyote.http11.Http11Protocol"

port="8443" minSpareThreads="5" maxSpareThreads="75"

enableLookups="true" disableUploadTimeout="true"

acceptCount="100" maxThreads="200"

scheme="https" secure="true" SSLEnabled="true"

keystoreFile="conf/.keystore"

keystorePass="changeit"

clientAuth="false" sslProtocol="TLS" useBodyEncodingForURI="true" />

SSO单点登录Spring-Security & CAS使用手册

重启Tomcat,访问https://hello.cas.server:8443/,出现以下界面说明HTTPS配置生效:

SSO单点登录Spring-Security & CAS使用手册

SSO单点登录Spring-Security & CAS使用手册

SSO单点登录Spring-Security & CAS使用手册

2.2.2部署 CAS WAR

CAS Server 是一个 Web 应用包,将解压后的文件夹中的 /module中的 cas-server-webapp-4.0.0.war 复制到 tomcat的 webapps 目录。将拷贝后的war文件重命名成 cas.war (会在webapps文件夹下自动解压出 cas 文件夹, 下文中将用%CAS_SERVER_HOME%来表示这个文件夹),由于前面已配置好 tomcat 的 https 协议,可以重新启动 tomcat,然后访问:https:// hello.cas.server:8443/cas ,如果能出现正常的 CAS 登录页面,则说明 CAS Server 已经部署成功。

SSO单点登录Spring-Security & CAS使用手册

虽然 CAS Server 已经部署成功,但这只是一个缺省的实现,在实际使用的时候,还需要根据实际概况做扩展和定制,最主要的是扩展认证 (Authentication) 接口和 CAS Server 的界面。

注意:cas-server4.0之前的默认验证规则:只要用户名和密码相同就认证通过

4.0 之后规则改了,默认是配置在 deployerConfigContext.xml 配置文件中,可以看到用户名密为 casuser/Mellon

路径:/usr/local/tomcat/webapps/cas/WEB-INF/deployerConfigContext.xml

SSO单点登录Spring-Security & CAS使用手册

SSO单点登录Spring-Security & CAS使用手册

SSO单点登录Spring-Security & CAS使用手册

(注:目录下给的cas.war里面已经包含了简单的jdbc配置,并且已经包含需要的jar包,配置人员配置时需要留意,参考修改配置。原war包可以从cas-server-4.0.0-release.zip下cas-server-4.0.0/ modules/ cas-server-webapp-4.0.0.war获得)

2.3扩展认证接口- JDBC 认证方法

用户的认证信息通常保存在数据库中,因此本文就选用这种情况来介绍。将前面下载的 cas-server-4.0.0-release.zip 包解开后,在 modules 目录下可以找到包 cas-server-support-jdbc-4.0.0.jar,其提供了通过 JDBC 连接数据库进行验证的缺省实现,基于该包的支持,我们只需要做一些配置工作即可实现 JDBC 认证。

JDBC 认证方法支持多种数据库,DB2, Oracle, MySql, Microsoft SQL Server 等均可,这里以 mysql 作为例子介绍。并且假设mysql数据库名: test,数据库登录用户名: root,数据库登录密码: 12345,用户信息表为: users。

DROP TABLE IF EXISTS `users`;

CREATE TABLE  `users` (

  `username` varchar(50) NOT NULL,

  `password` varchar(50) NOT NULL,

  `enabled` char(1) NOT NULL DEFAULT 'Y',

  PRIMARY KEY (`username`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

记住这里的表名users 和字段(username,password,enabled),后面要用到。

Insert into users values ('jim','', 'Y');

Insert into users values ('marry', '', 'Y');

1. 配置 DataStore

打开文件 %CATALINA_HOME%/webapps/cas/WEB-INF/deployerConfigContext.xml,添加一个新的 bean 标签,对于 mysql,内容如下:

<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://127.0.0.1:3306/test</value></property>

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

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

</bean>

其中 id 属性为该 DataStore 的标识,在后面配置 AuthenticationHandler 会被引用,另外,需要提供 DataStore 所必需的数据库驱动程序、连接地址、数据库登录用户名以及登录密码。

2. 配置 AuthenticationHandler

在 cas-server-support-jdbc-4.0.0.jar包中,提供了 3 个基于 JDBC 的 AuthenticationHandler,分别为 BindModeSearchDatabaseAuthenticationHandler, QueryDatabaseAuthenticationHandler, SearchModeSearchDatabaseAuthenticationHandler。其中 BindModeSearchDatabaseAuthenticationHandler 是用所给的用户名和密码去建立数据库连接,根据连接建立是否成功来判断验证成功与否;QueryDatabaseAuthenticationHandler 通过配置一个 SQL 语句查出密码,与所给密码匹配;SearchModeSearchDatabaseAuthenticationHandler 通过配置存放用户验证信息的表、用户名字段和密码字段,构造查询语句来验证。

使用哪个 AuthenticationHandler,需要在 deployerConfigContext.xml 中设置,默认情况下,CAS 使用一个简单的 username=password 的 AuthenticationHandler,在文件中可以找到如下一行:<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />,我们可以将其注释掉,换成我们希望的一个 AuthenticationHandler,这里我们使用QueryDatabaseAuthenticationHandle,如下。

使用 QueryDatabaseAuthenticationHandler

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

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

<property name="sql" value="select password from users where username=? and enabled='Y'" />

</bean>

<!—用到了上面定义的表名和字段-->

3. 部署依赖包

在以上配置完成以后,需要拷贝几个依赖的包到 cas 应用下,包括:

  • 将 cas-server-support-jdbc-4.0.0.jar 拷贝到 %CATALINA_HOME%/webapps/cas/ WEB-INF/lib 目录。
  • 数据库驱动,由于这里使用 mysql,将 mysql-connector-java-5.1.5-bin.jar 拷贝到 %CATALINA_HOME%/webapps/cas/WEB-INF/lib 目录。对于其他数据库,同样将相应数据库驱动程序拷贝到该目录。
  • DataStore 依赖于 commons-collections-3.2.jar, commons-dbcp-1.2.1.jar, commons-pool-1.3.jar,需要到 apache 网站的 Commons 项目下载以上 3 个包放进 %CATALINA_HOME%/webapps/cas/WEB-INF/lib 目录。
  • 注:目录下给的cas.war里面已经包含了简单的jdbc配置,并且已经包含需要的jar包,配置人员配置时需要留意,参考修改配置。原war包可以从cas-server-4.0.0-release.zip下cas-server-4.0/ modules/ cas-server-webapp-4.0.0.war获得。

2.4 扩展 CAS Server 界面

Demo先只应用cas server提供的默认登陆等页面,如后续需要修改相关页面,需要修改对应的view页面, 需要重新部署war包,CAS 的页面采用 Spring 框架编写(页面是Spring MVC),对于不熟悉 Spring 的开发者,在修改之前需要熟悉该框架。

参考链接:

http://www.cnblogs.com/vhua/p/cas_2.html

http://www.cnblogs.com/vhua/p/cas_3.html

3. 部署Spring Security应用

3.1准备工作

包括2.1的基本准备相关

spring-security-2.0.3.zip

cas-client-core-3.1.3.jar

重点:向CAS Server部署人员索取server.crt证书。然后导入该证书,这样CAS Server和Cas Client才能通过“握手”验证。

参考:

keytool -import -alias tomcat-cas-server -file "%JAVA_HOME%/jre/lib/security/server.crt" -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -storepass changeit

(注释:将server.crt导入jre的可信任证书仓库。注意,安装JDK是有两个jre目录,一个在jdk底下,一个是独立的jre,这里的目录必须同Tomcat使用的jre目录一致,否则后面Tomcat的HTTPS通讯就找不到证书了)

3.2开始部署Spring Security

3.2.1 开场简单介绍

单点登录的目的是为了让多个相关联的应用使用相同的登录过程,本文构造 2个简单的应用,来讲解如何部署spring-security & cas客户端子系统,分别以 springsecurity_cas_sample 和 springsecurity_cas_sample_brother 来作为示例,它结构相同,这 2 个应用使用同一套登录信息,并且只有登录过的用户才能访问。任何人都可以访问首页面, secure和extreme页面需要登陆验证,一旦经过验证,两个系统之间无须再次登陆验证。通过配置,实现单点登录,即只需登录一次就可以访问这两个应用。

下图为springsecurity_cas_sample的结构,springsecurity_cas_sample_brother与之相同。

SSO单点登录Spring-Security & CAS使用手册

3.2.2配置 CAS Filter

准备好springsecurity_cas_sample和 springsecurity_cas_sample_brother过后,分别部署在 B 和 C 机器上,这里假设CAS Server机器为A。由于 springsecurity_cas_sample和 springsecurity_cas_sample_brother,B 和 C 完全等同,我们以 springsecurity_cas_sample 在 B 机器上的配置做介绍,根据上文的cas server的配置,假设 A 和 B 的域名分别为 domainA为hello.cas.server:8443 和 domainB为hello.cas.server:8080 (由于笔者只有一台机器)。

将 casclient.jar,cas-client-core-3.1.3.jar,spring-security-cas-client-2.0.3.jar,spring-security-core-2.0.3.jar,spring.jar,log4j-1.2.15.jar,mysql-connector-java-5.1.5-bin.jar 并拷贝到 /WEB-INF/lib目录下,修改 web.xml 文件,添加 CAS Filter,如下所示:

<context-param>

              <param-name>contextConfigLocation</param-name>

              <param-value>

/WEB-INF/applicationContext-security.xml

              </param-value>

       </context-param>

    <context-param>

        <param-name>log4jConfigLocation</param-name>

        <param-value>/WEB-INF/classes/log4j.properties</param-value>

    </context-param>

       <context-param>

        <param-name>log4jExposeWebAppRoot</param-name>

        <param-value>false</param-value>

    </context-param>

       <filter>

          <filter-name>CAS Single Sign Out Filter</filter-name>

          <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>

       </filter>

    <filter>

        <filter-name>springSecurityFilterChain</filter-name>

        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

    </filter>

       <filter-mapping>

          <filter-name>CAS Single Sign Out Filter</filter-name>

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

       </filter-mapping>

    <filter-mapping>

      <filter-name>springSecurityFilterChain</filter-name>

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

    </filter-mapping>

       <!--

         - Loads the root application context of this web app at startup.

         - The application context is then available via

         - WebApplicationContextUtils.getWebApplicationContext(servletContext).

    -->

       <listener>

              <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>

       </listener>

       <listener>

              <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

       </listener>

    <listener>

        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>

    </listener>   

    <!--

         - Publishes events for session creation and destruction through the application

         - context. Optional unless concurrent session control is being used.

      -->

    <listener>

      <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>

    </listener>

配置实例

Web.xml中,Spring-Security 的applicationContext-security.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:sec="http://www.springframework.org/schema/security"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">

    <!--xmlns:sec="http://www.springframework.org/schema/security" -->

    <!--定义security 的命名空间是sec-->

<sec:http entry-point-ref="casProcessingFilterEntryPoint">

<sec:intercept-url pattern="/secure/extreme/**" access="ROLE_SUPERVISOR" />

<sec:intercept-url pattern="/secure/**" access="ROLE_USER" />

<sec:logout logout-success-url="/cas-logout.jsp"/>

</sec:http>

    <!--定义secure受保护页,和访问角色,具体用户角色定义在上文的jdbc中有介绍。 -->

<sec:authentication-manager alias="authenticationManager"/>

<bean id="casProcessingFilter" class="org.springframework.security.ui.cas.CasProcessingFilter">

<sec:custom-filter after="CAS_PROCESSING_FILTER"/>

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

<property name="authenticationFailureUrl" value="/casfailed.jsp"/>

<property name="defaultTargetUrl" value="/"/>

</bean>

<!--authenticationFailureUrl登陆失败时转向的页面

defaultTargetUrl登陆成功时转向的页面  -->

<bean id="casProcessingFilterEntryPoint" class="org.springframework.security.ui.cas.CasProcessingFilterEntryPoint">

<property name="loginUrl" value="https://hello.cas.server:8443/cas/login"/>

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

</bean>

    <!-- loginUrl定义CAS server登陆页面,A的地址-->

<bean id="casAuthenticationProvider" class="org.springframework.security.providers.cas.CasAuthenticationProvider">

<sec:custom-authentication-provider />

<property name="userDetailsService" ref="userService"/>

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

<property name="ticketValidator">

<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">

<constructor-arg index="0" value="https://hello.cas.server:8443/cas" />

</bean>

</property>

<property name="key" value="an_id_for_this_auth_provider_only"/>

</bean>

<bean id="proxyGrantingTicketStorage" class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl" />

<bean id="serviceProperties" class="org.springframework.security.ui.cas.ServiceProperties">

<property name="service" value="http://hello.cas.server:8080/springsecurity_cas_sample/j_spring_cas_security_check"/>

<property name="sendRenew" value="false"/>

</bean>

    <!-- service定义子系统server地址,B的地址-->

     <sec:jdbc-user-service data-source-ref="dataSource" id="userService"

     users-by-username-query="select myusername,myauthority,1 from authorities_sub1 where myusername=?"

     authorities-by-username-query="select myusername,myauthority from authorities_sub1 where myusername=?"

     />

<!-- service定义子系统的权限表,必须包含用户名字段和权限字段,权限字段的值必须以ROLE_开头,应用的数据库在后面(dataSource).

web配置实例

举例:

CREATE TABLE `authorities_sub1` (

  `myusername` varchar(50) NOT NULL,

  `myauthority` varchar(50) NOT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into authorities_sub1 values('marry', 'ROLE_USER');

insert into authorities_sub1 values('jim', 'ROLE_SUPERVISOR');

insert into authorities_sub1 values('jim', 'ROLE_USER');

-->

     <!—采用jdbc方式获得用户权限,这里默认管理的用户和权限表为上文jdbc配置的表-->

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

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

<property name="url" value="jdbc:mysql://127.0.0.1:3306/subdb"/>

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

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

</bean>

<!-- service定义子通过jdbc连接数据库,连接自定义需要连接的数据库,用户名,密码-->  

</beans>

在上面所有配置结束过后,分别在 A, B, C上启动tomcat(由于笔者只有一台机器,故一次启动), springsecurity_cas_sample 和 springsecurity_cas_sample_brother,按照下面步骤来访问 springsecurity_cas_sample和 springsecurity_cas_sample_brother:

1. 打开浏览器

访问 http://hello.cas.server:8080/springsecurity_cas_sample/ ,如图所示:

SSO单点登录Spring-Security & CAS使用手册

2. 点击Secure page链接

浏览器会弹出安全提示,接受后即转到 CAS 的登录页面,如图所示:

SSO单点登录Spring-Security & CAS使用手册

3. 登录成功后

再重定向到 springsecurity_cas_sample 的 Secure page 页面,如所示:

SSO单点登录Spring-Security & CAS使用手册

4. 再在同一个浏览器中

点击 springsecurity_cas_sample_brother/secure/index.jsp链接 ,系统不再提示用户登录,而直接出现如图所示的页面,并且显示在 springsecurity_cas_sample 中已经登录过的用户。

5. 反之先登陆springsecurity_cas_sample_brother

再登陆springsecurity_cas_sample效果一样。

springsecurity_cas_sample和springsecurity_cas_sample_brother代码程序在svn上

svn://192.168.0.5/research/trunk/SSO/springsecurity_cas_sample

svn://192.168.0.5/research/trunk/SSO/springsecurity_cas_sample_brother

3.3 Spring-Security子系统API

为辅助开发,提供api如下,SSOUtil.java

/******************************************************************/

/**

* 获得当前登录用户名 (推荐)

* @param

* @return 当前用户名

* @throws Exception

*/

public static String getCurrentUserName();

/******************************************************************/

/**

* 获得当前登录用户名

* @param request

* @return 当前用户名

* @throws Exception

*/

public static String getCurrentUserName(HttpServletRequest request);

/******************************************************************/

/**

* 获得当前登录用户拥有的所有role(推荐)

* @param

* @return 角色数组

* @throws Exception

*/

public static String[] getCurrentUserRoles();

/******************************************************************/

/**

* 获得当前登录用户拥有的所有role

* @param request

* @return 角色数组

* @throws Exception

*/

public static String[] getCurrentUserRoles(HttpServletRequest request);

/******************************************************************/

/**

* 判断当前登录用户的角色是否是指定的role

* @param request

* @param role

* @return boolean

* @throws Exception

*/

public static boolean isCurrentUserRole(HttpServletRequest request, String role)

实例代码

结束语

本文介绍了 CAS 单点登录解决方案的原理,并结合实例讲解了在 Tomcat 中使用 CAS & Spring Security的配置、部署方法以及效果。CAS 是作为开源单点登录解决方案的一个不错选择,更多的使用细节可以参考 CAS 官方网站。