基于CAS的单点登录系统

  |   0 评论   |   1,071 浏览

概述

单点登录

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

CAS 介绍

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

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

  • 基于Java

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

CAS 原理和协议

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

1.jpg

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

部署

配置 Tomcat 使用 Https 协议

生成Keystore

证书是单点登录认证系统中很重要的一把钥匙,客户端于服务器的交互安全靠的就是证书。在此,主要讲解用JDK自带的keytool工具生成证书。 

进入命令提示符,输入以下指令:

keytool -genkey -alias casserver -keypass demosso -keyalg RSA -keystore casserver.keystore -validity 365

参数介绍

  • -alias 密钥的别名 

  • -keyalg 密钥使用的加密算法,此处使用RSA 

  • -keystore 密钥存储的位置,默认是存在用户主目录下,此处则指定存储位置 

更多关于keytool的参数说明请参考《JDK keytool参数说明》

此条命令的意思就是在当前目录下,使用RSA加密算法生成一个别名为demosso的casserver.keystore,生成keystore的过程如图2所示:

您的名字与姓氏是什么?
 [cxy7.com]: cxy7.com
您的组织单位名称是什么?
 [Ctrip]: 
您的组织名称是什么?
 [JW]: 
您所在的城市或区域名称是什么?
 [Bj]: 
您所在的省/市/自治区名称是什么?
 [BJ]: 
该单位的双字母国家/地区代码是什么?
 [CN]: 
CN=cxy7.com, OU=Ctrip, O=JW, L=Bj, ST=BJ, C=CN是否正确?
 [否]: y

导出证书

[root@cxy7 cas]# keytool -export -alias casserver -storepass demosso -file casserver.cer -keystore casserver.keystore

存储在文件 <casserver.cer> 中的证书

[root@cxy7 cas]# ll
总用量 8
-rw-r--r-- 1 root root  847 3月  15 11:19 casserver.cer
-rw-r--r-- 1 root root 2202 3月  15 11:17 casserver.keystore

给运行Tomcat的服务器导入证书

[root@cxy7 cas]# keytool -export -alias casserver -storepass demosso -file casserver.cer -keystore casserver.keystore

存储在文件 <casserver.cer> 中的证书

[root@cxy7 cas]# keytool -import -trustcacerts -alias casserver -storepass demosso -file casserver.cer -keystore cacerts
所有者: CN=cxy7.com, OU=Ctrip, O=JW, L=Bj, ST=BJ, C=CN
发布者: CN=cxy7.com, OU=Ctrip, O=JW, L=Bj, ST=BJ, C=CN
序列号: 7e26dfaa
有效期开始日期: Tue Mar 15 14:28:27 CST 2016, 截止日期: Wed Mar 15 14:28:27 CST 2017
证书指纹:
MD5: D4:A9:C7:01:3B:87:9D:71:5C:CB:EA:23:7A:4B:62:49
SHA1: 29:73:74:08:C2:86:80:70:B9:27:73:36:AC:3F:67:F0:03:99:92:EB
SHA256: 39:4D:95:7F:9A:2D:AF:E1:E7:CB:32:EB:71:92:D7:CC:59:BC:A6:55:0C:61:D7:B7:D7:9D:51:D4:73:D4:A2:E5
签名算法名称: SHA256withRSA
版本: 3
扩展:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: C4 6B 9C 05 AE 69 52 A9 DE E9 C8 C3 F9 79 08 FE .k...iR......y..
0010: 14 1A 57 38 ..W8
]
]
是否信任此证书? [否]: y
证书已添加到密钥库中

修改Tomcat配置文件

注释

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

添加

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="/usr/local/tomcat-cas/casserver.keystore" keystorePass="demosso" truststoreFile="/usr/local/tomcat-cas/cacerts"
clientAuth="false" sslProtocol="TLS" />

编译CAS

下载源码

git clone https://github.com/apereo/cas.git

编译

mvn clean package -DskipTests

获取war包

cas-server-webapp/target/cas.war

验证

访问:https://192.168.1.111:8443/cas/login

用户名:casuser,密码:Mellon

2.png

登录成功

3.png

配置CAS使用Mysql数据库的用户信息

添加jar包

在webapps/cas/WEB-INF/lib下添加cas-server-support-jdbc-4.1.5.jar和mysql-connector-java-5.1.38.jar

创建库表信息

CREATE DATABASE cas;

CREATE TABLE `app_user` (
	`username` VARCHAR (30) NOT NULL DEFAULT '',
	`password` VARCHAR (45) NOT NULL DEFAULT '',
	PRIMARY KEY (`username`)
) ENGINE = INNODB DEFAULT CHARSET = utf8;

INSERT INTO `app_user` (`username`, `password`)
VALUES
	('test', 'test'),
	('test1', 'test1');

编辑webapps/cas/WEB-INF/deployerConfigContext.xml

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://192.168.1.112:3306/cas?useUnicode=true&amp;characterEncoding=utf-8&amp;createDatabaseIfNotExist=true</value>
</property>
<property name="username">
<value>XXXX</value>
</property>
<property name="password">
<value>XXXXX</value>
</property>
</bean>

<bean id="primaryAuthenticationHandler" class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="sql" value="select password from app_user where username=?" />
<property name="dataSource" ref="dataSource" />
</bean>

验证

以test|test用户登录


读后有收获可以支付宝请作者喝咖啡