CAS 单点登录系统
一、什么是单点登录
单点登录(Sign Sion On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。对于存在诸多子系统且子系统分别部署到不同的服务器中,那么使用传统的 session 是无法解决的,就需要使用单点登录技术来解决。
如图:第一次访问应用系统1时,会自动跳转到认证系统进行登录,当登录成功时返回 ticket(票据)存储在用户本地,类似于 Cookie。当用户第二次访问应用系统2时,会将 ticket 传送过去,应用系统2与认证系统之间进行 ticket 的验证(系统内部的交互,不会进行页面之间的跳转,用户基本感受不到)验证成功后进入应用系统2中。其余系统访问与应用系统2相同。

二、什么是 CAS
CAS 是 Yale 大学发起的一个开源项目,目的为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 04 年正式成为 JA-SIG 的一个项目。CAS 具有如下特点:
● 开源的企业级单点登录解决方案。
● CAS Server 为需要独立部署的 Web 应用,换句话说就是一个 war 包,直接放入Tomcat 进行使用。
● CAS Client 支持非常多的客户端(指的是非常多的 Web 应用),包括 Java、.Net、PHP、Apache、Ruby 等
从结构上看,CAS 包含两个部分:CAS Server 和 CAS Client。CAS Server 需要独立部署,主要负责对用户的认证工作;CAS Client(用户的应用系统) 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 CAS Server,下图是 CAS 最基本的协议过程。
SSO 单点登录访问流程主要有以下步骤:
1)、访问服务:SSO 客户端发送请求访问应用系统提供的服务资源。
2)、定向认证:SSO 客户端会重定向用户请求到 SSO 服务器。
3)、用户认证:用户身份认证,认证成功后返回 Ticket 票据信息。
4)、发送票据:SSO 服务器会产生一个随机的 Server Ticket。
5)、验证票据:SSO 服务器验证票据 Service Ticket 的合法性,验证通过后,允许客户端访问服务。
6)、传送用户信息:SSO 服务器验证票据通过后,传输用户认证结果信息给客户端。
三、CAS 服务端部署
CAS 服务端其实就是一个 war 包(cas-server-webapp-4.0.0.war),将其改名为 cas.war 放入 Tomcat 目录下的 webapps 下。启动 Tomcat 自动解压 war 包,在浏览器中输入 http://localhost:8080/cas/login 可以看到登录页面:默认登录用户名 casuser,密码 Mellon
四、服务端配置
【1】如果不希望用 8080 端口访问 CAS 可以修改端口:打开 Tomcat 目录 conf/server.xml 修改如下内容:将 8080 修改为你想要的端口(9100)
1 <!--<Connector port="8080" protocol="HTTP/1.1"
2 connectionTimeout="20000"
3 redirectPort="8443" />(原配置文件)-->
4 <Connector port="9100" protocol="HTTP/1.1"
5 connectionTimeout="20000"
6 redirectPort="8443" />
修改 CAS 配置文件:cas 项目中的 WEB-INF/cas.properties
1 #server.name=http://localhost:8080(原配置内容) 修改为自己的IP和端口
2 server.name=http://192.68.88.129:9100
【2】去除 Https 认证
CAS默认使用的是 HTTPS 协议,如果使用 HTTPS 协议需要 SSL 安全证书(需要向特定的机构申请和购买)。如果安全要求不高或者是开发测试阶段, 可使用 HTTP协议。我们这里讲解通过修改配置,让 CAS使用 HTTP协议。
修改 cas 的 WEB-INF/deployerConfigContext.xml 修改配置文件:这里需要增加参数 p:requireSecure="false", requireSecure 属性意思为是否需要安全验证,即 HTTPS,false 为不采用
1 <bean id="proxyAuthenticationHandler"
2 class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
3 p:httpClient-ref="httpClient" />
修改 cas 的 /WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml 找到下面配置:
参数 p:cookieSecure="true",同理为HTTPS验证相关,true为采用 HTTPS 验证,false 为不采用 https 验证。
参数 p:cookieMaxAge="-1",是 COOKIE的最大生命周期,-1为无生命周期,即只在当前打开的窗口有效,关闭或重新打开其它窗口,仍会要求验证。可以根据需要修改为大于0的数字,比如3600等,意思是在 3600秒内,打开任意窗口,都不需要验证。
我们这里将 cookieSecure改为false , cookieMaxAge 改为3600
1 <bean id="ticketGrantingTicketCookieGenerator"
2 class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
3 p:cookieSecure="true"
4 p:cookieMaxAge="-1"
5 p:cookieName="CASTGC"
6 p:cookiePath="/cas" />
修改 cas的 WEB-INF/spring-configuration/warnCookieGenerator.xml 找到下面配置:这里将cookieSecure改为false , cookieMaxAge 改为3600
1 <bean id="warnCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
2 p:cookieSecure="true"
3 p:cookieMaxAge="-1"
4 p:cookieName="CASPRIVACY"
5 p:cookiePath="/cas" />
五、CAS 入门客户端 Demo
【1】搭建 maven Project 工程(cas_demo1 与 cas_demo2 两个工程)引入 cas 客户端依赖并定制 tomcat 运行端口分别为 9001 和 9002
1 <dependencies>
2 <!-- cas -->
3 <dependency>
4 <groupId>org.jasig.cas.client</groupId>
5 <artifactId>cas-client-core</artifactId>
6 <version>3.3.3</version>
7 </dependency>
8
9 <dependency>
10 <groupId>javax.servlet</groupId>
11 <artifactId>servlet-api</artifactId>
12 <version>2.5</version>
13 <scope>provided</scope>
14 </dependency>
15 </dependencies>
16 <build>
17 <plugins>
18 <plugin>
19 <groupId>org.apache.maven.plugins</groupId>
20 <artifactId>maven-compiler-plugin</artifactId>
21 <version>2.3.2</version>
22 <configuration>
23 <source>1.7</source>
24 <target>1.7</target>
25 </configuration>
26 </plugin>
27 <plugin>
28 <groupId>org.apache.tomcat.maven</groupId>
29 <artifactId>tomcat7-maven-plugin</artifactId>
30 <configuration>
31 <!-- 指定端口 -->
32 <port>9002</port>
33 <!-- 请求路径 -->
34 <path>/</path>
35 </configuration>
36 </plugin>
37 </plugins>
38 </build>
【2】webapp 文件下创建 WEB-INF/web.xml 文件,内容如下:需要修改本地服务的地址和 CAS 服务器的地址。
1 <?xml version="1.0" encoding="UTF-8"?>
2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xmlns="http://java.sun.com/xml/ns/javaee"
4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
5 version="2.5">
6
7 <!-- ======================== 单点登录开始 ======================== -->
8 <!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置 -->
9 <listener>
10 <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
11 </listener>
12
13 <!-- 该过滤器用于实现单点登出功能,可选配置。 -->
14 <filter>
15 <filter-name>CAS Single Sign Out Filter</filter-name>
16 <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
17 </filter>
18 <filter-mapping>
19 <filter-name>CAS Single Sign Out Filter</filter-name>
20 <url-pattern>/*</url-pattern>
21 </filter-mapping>
22
23 <!-- 该过滤器负责用户的认证工作,必须启用它 -->
24 <filter>
25 <filter-name>CASFilter</filter-name>
26 <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
27 <init-param>
28 <param-name>casServerLoginUrl</param-name>
29 <!--这里的server是服务端的IP -->
30 <param-value>http://192.168.88.129:9100/cas/login</param-value>
31 </init-param>
32 <init-param>
33 <param-name>serverName</param-name>
34 <!-- 当前系统的地址 因为cas 认证成功后需要跳转到当前的系统中 -->
35 <param-value>http://localhost:9002</param-value>
36 </init-param>
37 </filter>
38 <filter-mapping>
39 <filter-name>CASFilter</filter-name>
40 <url-pattern>/*</url-pattern>
41 </filter-mapping>
42
43 <!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->
44 <filter>
45 <filter-name>CAS Validation Filter</filter-name>
46 <filter-class>
47 org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
48 <init-param>
49 <param-name>casServerUrlPrefix</param-name>
50 <param-value>http://192.168.88.129:9100/cas</param-value>
51 </init-param>
52 <init-param>
53 <param-name>serverName</param-name>
54 <param-value>http://localhost:9002</param-value>
55 </init-param>
56 </filter>
57 <filter-mapping>
58 <filter-name>CAS Validation Filter</filter-name>
59 <url-pattern>/*</url-pattern>
60 </filter-mapping>
61
62 <!-- 该过滤器负责实现HttpServletRequest请求的包裹, 比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。 -->
63 <filter>
64 <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
65 <filter-class>
66 org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
67 </filter>
68 <filter-mapping>
69 <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
70 <url-pattern>/*</url-pattern>
71 </filter-mapping>
72
73 <!-- 该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。 比如AssertionHolder.getAssertion().getPrincipal().getName()。 -->
74 <filter>
75 <filter-name>CAS Assertion Thread Local Filter</filter-name>
76 <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
77 </filter>
78 <filter-mapping>
79 <filter-name>CAS Assertion Thread Local Filter</filter-name>
80 <url-pattern>/*</url-pattern>
81 </filter-mapping>
82
83 <!-- ======================== 单点登录结束 ======================== -->
84 </web-app>
【3】webapp 中编写 index.jsp 页面,保持页面中的内容不同即可(用于服务两个服务)
1 <%@ page language="java" contentType="text/html; charset=utf-8"
2 pageEncoding="utf-8"%>
3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
7 <title>CAS DEMO2</title>
8 </head>
9 <body>
10 欢迎来到CAS DEMO2
11 <%=request.getRemoteUser()%>
12 </body>
13 </html>
【4】通过 Run As - maven build... - Golas:clean tomcat7:run 当第一次访问本地项目 demo1 时,自动跳转至 CAS 登录页面,登录成功后跳转至 Demo1 的 index.jsp 页面中,当再次访问本地项目 demo2 时,就不用进行登录直接,进入项目 demo2 的index.jsp 页面:

六、单点退出登录
单点登录链接:http://192.168.88.129:9100/cas/logout 既退出所有节点的用户登录。便可看到登出提示页面:
如果我们希望退出登录后,自动跳转到某个自己设定的页面,需要做如下修改:
【1】修改 cas系统的配置文件 cas-servlet.xml ,将 p:followServiceRedirects 中的 false 修改为 true 既可以重定向。
1 <bean id="logoutAction" class="org.jasig.cas.web.flow.LogoutAction"
2 p:servicesManager-ref="servicesManager"
3 p:followServiceRedirects="${cas.logout.followServiceRedirects:false}"/>
【2】改为 true 后,可以在退出时跳转页面到目标页面,修改 index.jsp 的退出链接,在连接中添加 service= 目标地址
<a href="http://localhost:9100/cas/logout?service=http://www.baidu.com">退出登录</a>
七、CAS 服务端数据源设置 (用户信息从数据库中获取)
修改cas服务端中 web-inf 下 deployerConfigContext.xml ,添加如下配置
1 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
2 p:driverClass="com.mysql.jdbc.Driver"
3 p:jdbcUrl="jdbc:mysql://127.0.0.1:3306/pinyougoudb?characterEncoding=utf8"
4 p:user="root"
5 p:password="123456" />
6 <!--密码加密的算法-->
7 <bean id="passwordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"
8 c:encodingAlgorithm="MD5"
9 p:characterEncoding="UTF-8" />
10 <bean id="dbAuthHandler"
11 class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"
12 p:dataSource-ref="dataSource"
13 p:sql="select password from tb_user where username = ?"
14 p:passwordEncoder-ref="passwordEncoder"/>
然后在配置文件开始部分找到如下配置
1 <bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
2 <constructor-arg>
3 <map>
4 <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
5 <entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />
6 </map>
7 </constructor-arg>
8 <property name="authenticationPolicy">
9 <bean class="org.jasig.cas.authentication.AnyAuthenticationPolicy" />
10 </property>
11 </bean>
其中 <entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" /> 一句是使用固定的用户名和密码,我们在下面可以看到这两个bean ,如果我们使用数据库认证用户名和密码,需要将这句注释掉。添加下面这一句配置 <entry key-ref="dbAuthHandler" value-ref="primaryPrincipalResolver"/> 修改后如下:
1 <constructor-arg>
2 <map>
3 <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
4 <entry key-ref="dbAuthHandler" value-ref="primaryPrincipalResolver" />
5 </map>
6 </constructor-arg>
将上面配置的三个 Bean 所涉及的 jar 包放入webapps\cas\WEB-INF\lib 下 
八、优缺点
优点 :用户身份信息独立管理,更好的分布式管理。同时, 可以自己扩展安全策略;
缺点:认证服务器访问压力较大。需要根据自己系统的情况判断是否选择使用SSO;

----架构师资料,关注公众号获取----
CAS 单点登录系统的更多相关文章
- CAS单点登录系统整合——注册的问题
最近一段时间在搞CAS单点登录系统,涉及到几个子系统的整合问题.对于注册,这里遇到了一个选择: 在子系统内完成注册,然后把信息同步到CAS系统: 在CAS系统中完成基本信息的注册,比如:用户名.邮箱. ...
- CAS单点登录系统入门--分布式登录验证
1.开源单点登录系统CAS入门 1.1 什么是单点登录 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要 ...
- cas单点登录系统:客户端(client)详细配置(包含统一单点注销配置)
最近一直在研究cas登录中心这一块的应用,分享一下记录的一些笔记和心得.后面会把cas-server端的配置和重构,另外还有这几天再搞nginx+cas的https反向代理配置,以及cas的证书相关的 ...
- CAS单点登录系统--进阶
2.CAS服务端数据源设置 2.1需求分析 我们现在让用户名密码从我们的优乐选的user表里做验证 2.2配置数据源 (1)修改cas服务端中web-inf下deployerConfigContext ...
- cas单点登录系统:客户端(client)详细配置
最近一直在研究cas登录中心这一块的应用,分享一下记录的一些笔记和心得.后面会把cas-server端的配置和重构,另外还有这几天再搞nginx+cas的https反向代理配置,以及cas的证书相关的 ...
- CAS单点登录系统简介
一.cas简介 全名:Central Authentication Service特点: 1.开源的.多协议的 SSO 解决方案: Protocols : Custom Protocol . CAS ...
- SSO之CAS单点登录详细搭建教程
本教程是我个人编写,花费几个小时的时间,给需要学习的人员学习使用,希望能帮助到你们. [环境说明]:本文演示过程在同一个机器上的(也可以在三台实体机器或者三个的虚拟机上),环境如下: windows7 ...
- cas系列(一)--cas单点登录基本原理
(这段时间打算做单点登录,因此研究了一些cas资料并作为一个系列记录下来,一来可能会帮助一些人,二来对我自己所学知识也是一个巩固.) 一.为什么要实现单点登录 随着信息化不断发展,企业的信息化过程是一 ...
- 单点登录系统(SSO)之CAS(中央认证服务)
SSO(Single Sign On)单点登录系统,是在多个系统中值要求只要登录一次,就可以用已登录的身份访问多个系统,去掉了每次访问不同的系统都要重新登录的弊端. CAS(中央/集中认证服务):Th ...
- 单点登录系统CAS筹建及取得更多用户信息的实现
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
随机推荐
- nodejs redis执行lua脚本
const Redis = require("ioredis"); const redis = new Redis({ port: 6300, // Redis port host ...
- Mysql学习:3、sql数据类型及命令
1.sql功能分类: 2.常见数据类型: 3.sql命令: DDL命令: a.创建数据库: create database testdatabase(数据库名称) character set utf8 ...
- 解决tomcat8080端口占用问题
解决tomcat8080端口占用问题 1. 使用管理员权限打开cmd 2. 输入 netstat -ano | findstr 8080 找出占用8080端口的进程pid netstat -ano | ...
- libev中的__attribute__优化
在学习libev的过程中,遇到了大量的__attribute__优化方式,此文章将它们做一个汇总和介绍,并会持续更新 1.unused:使编译器忽略未使用的函数或者变量 源码如下 1 //判断如果gc ...
- mybatis lombok 报错: java: java.lang.IllegalAccessError: class lombok.javac.apt.LombokProcessor
1. 报错原因:jdk版本太高,lombok版本太低 2. 解决办法:安装更高版本的依赖包,可以去Maven Repository: lombok去查:https://mvnrepository.co ...
- SQL注入绕过某waf的详细过程。
0x00起因 看到大家都有绕waf的payload,想了想,这样下去不行啊.总不能找人家要吧,于是我开启了电脑,开始我的bypass之路. 0x01过程 准备完毕后,开始,首先判断注入and 1=1 ...
- JAVA——》微信分账
做一个推荐分享的功能,场景:每推荐成功奖励推荐人一定的推荐金. 这里,我就用调用了微信支付分账接口.链接:https://pay.weixin.qq.com/wiki/doc/api/allocati ...
- fiddler 实现跨域
static function OnBeforeResponse(oSession: Session) { ... if(oSession.uriContains("要处理的url" ...
- Git Peer reports incompatible or unsupported protocol version
今天用git克隆一个项目的时候出现标题中的错误 fatal: unable to access 'xxx.git/': Peer reports incompatible or unsupported ...
- 字节过滤流 --->对象流(存入对象的)----> ObjectOutputStream: 用法
前提:1).要有一个类 并创建这个类的对象2)要让类必须继承Serializable接口3)transient修饰的属性 值不参与序列化1创建字节输出节点流FileOutputStream fos = ...