CAS学习笔记三:SpringBoot自动配置与手动配置过滤器方式集成CAS客户端
本文目标
基于SpringBoot + Maven 分别使用自动配置与手动配置过滤器方式集成CAS客户端。
需要提前搭建 CAS 服务端,参考 https://www.cnblogs.com/hellxz/p/15740935.html
代码已上传本人 GitHub https://github.com/hellxz/cas-integration-demo
代码目录结构
代码实现
父工程 cas-integration-demo
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hellxz</groupId>
<artifactId>cas-integration-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<modules>
<!-- 自动配置demo A -->
<module>demo-a-auto-config</module>
<!-- 手动配置demo B -->
<module>demo-b-manual-config</module>
</modules>
<properties>
<java.version>1.8</java.version>
<!-- 指定cas客户端版本 -->
<cas.client.version>3.6.3</cas.client.version>
</properties>
<dependencies>
<!-- 引入web starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
自动配置工程 demo-a-auto-config
下文简称此工程为
服务A
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.hellxz</groupId>
<artifactId>cas-integration-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>demo-a-auto-config</artifactId>
<dependencies>
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-support-springboot</artifactId>
<version>${cas.client.version}</version>
</dependency>
</dependencies>
</project>
com.hellxz.cas.CasAutoConfigApp.java
package com.hellxz.cas;
import javax.servlet.http.HttpServletRequest;
import org.jasig.cas.client.boot.configuration.EnableCasClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
@EnableCasClient //<--自动配置只需要启用此注解
public class CasAutoConfigApp {
public static void main(String[] args) {
SpringApplication.run(CasAutoConfigApp.class, args);
}
@GetMapping("/test")
public String test(HttpServletRequest request) {
return "服务A测试通过";
}
}
application.properties
server.port=8081
#CAS配置,更多参数见https://github.com/apereo/java-cas-client#spring-boot-autoconfiguration
#cas服务端地址
cas.server-url-prefix=http://192.168.56.104:8080/cas
#cas服务端登录地址
cas.server-login-url=http://192.168.56.104:8080/cas/login
#当前服务地址
cas.client-host-url=http://10.2.6.63:8081
#校验ticket使用的协议,可选: CAS(代表CAS2)、CAS3、SAML
cas.validation-type=CAS3
注意替换 CAS 服务端地址 及 客户端 IP
手动配置工程 demo-b-manual-config
下文简称此工程为
服务B
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.hellxz</groupId>
<artifactId>cas-integration-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>demo-b-manual-config</artifactId>
<dependencies>
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>${cas.client.version}</version>
</dependency>
</dependencies>
</project>
com.hellxz.cas.CasManualConfigApp.java
package com.hellxz.cas;
import javax.servlet.http.HttpServletRequest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class CasManualConfigApp {
public static void main(String[] args) {
SpringApplication.run(CasManualConfigApp.class, args);
}
@GetMapping("/test")
public String test(HttpServletRequest request) {
return "服务B测试通过";
}
}
com.hellxz.cas.Config.java
package com.hellxz.cas;
import java.util.HashMap;
import java.util.Map;
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
@Configuration
public class Config {
/**
* 自定义cas服务地址
*/
@Value("${custom.cas.casServerUrlPrefix:}")
private String casServerUrlPrefix;
/**
* 自定义服务标识,格式为{protocol}:{hostName}:{port}
*/
@Value("${custom.cas.serverName:}")
private String serverName;
/**
* 拦截所有请求,将未携带票据与会话中无票据的请求都重定向到CAS登录地址
*/
@Bean
@Order(1)
public FilterRegistrationBean<AuthenticationFilter> casAuthenticationFilter() {
FilterRegistrationBean<AuthenticationFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new AuthenticationFilter());
registration.setName("CAS Authentication Filter");
Map<String, String> initParams = new HashMap<>();
initParams.put("casServerUrlPrefix", casServerUrlPrefix); // CAS服务端地址,会拼接为登录地址
initParams.put("serverName", serverName); // 服务地址
registration.setInitParameters(initParams);
registration.addUrlPatterns("/*");
return registration;
}
/**
* 拦截所有请求,使用获取的票据向CAS服务端发起校验票据请求
*/
@Bean
@Order(2)
public FilterRegistrationBean<Cas30ProxyReceivingTicketValidationFilter> cas30TicketValidationFilter() {
FilterRegistrationBean<Cas30ProxyReceivingTicketValidationFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new Cas30ProxyReceivingTicketValidationFilter());
registration.setName("CAS30 Ticket Validation Filter");
Map<String, String> initParams = new HashMap<>();
initParams.put("casServerUrlPrefix", casServerUrlPrefix); // CAS服务端地址,会拼接为服务校验地址
initParams.put("serverName", serverName);
registration.setInitParameters(initParams);
registration.addUrlPatterns("/*");
return registration;
}
/**
* 包装HttpServletRequest,使CAS登录成功的用户名等信息存入请求中<br>
* <br>
* 登录成功后以下两个方法将不再返回null: <br>
*
* <pre>
* HttpServletRequest#getUserPrincipal()
* HttpServletRequest#getRemoteUser()
* </pre>
*/
@Bean
@Order(3)
public FilterRegistrationBean<HttpServletRequestWrapperFilter> httpServletRequestWrapperFilter() {
FilterRegistrationBean<HttpServletRequestWrapperFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new HttpServletRequestWrapperFilter());
registration.setName("HttpServletRequest Wrapper Filter");
registration.addUrlPatterns("/*");
return registration;
}
}
application.properties
server.port=8082
#cas服务端地址
custom.cas.casServerUrlPrefix=http://192.168.56.104:8080/cas
#当前服务地址
custom.cas.serverName=http://10.2.6.63:8082
注意替换 CAS 服务端地址 及 客户端 IP
验证单点登录流程
1、分别启动 demo-a-auto-config
与 demo-b-manual-config
2、打开浏览器输入 demo部署的IP:8081/test
,访问服务A,访问后立即跳转CAS登录
3、输入默认用户名/密码 casuser/Mellon
,登录成功返回服务A的字样,让我们看看登录请求后发生了什么:
登录成功后,响应头Set-Cookie回写了名为 TGC 的Cookie,并且还有 Location 重定向,URL上传了 ST (服务票据)
重定向到服务A,服务A验证ST(忽略此流程,它不在浏览器端体现),校验通过回写Cookie,重定向回服务A的 /test
接口
接着访问服务A接口,完成响应,此时服务A单点登录已经成功了。
4、清网络记录,再访问服务B的接口 服务B地址:8081/test
,可以看到立即跳转成功了,查看下请求,主要是 /cas/login 请求
后边校验ST重定向与访问服务A时过程一致,不再赘述。CAS单点登录验证通过。
代码解释
自动配置demo(服务A)
SpringBoot集成CAS客户端比较简单,此处用的是官方方式。首先引入自动配置依赖,并启用 @EnableCasClient
注解
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-support-springboot</artifactId>
<version>${cas.client.version}</version>
</dependency>
此依赖引用了 cas-client-core.jar
(核心包)与 cas-client-support-saml.jar
(saml验签协议支持),另外 cas-client-support-springboot.jar
中还有配置类
其中:
1、EnableCasClient
注解类引入了配置类 CasClientConfiguration
2、CasClientConfiguration
配置类中使用 CasClientConfigurationProperties
读取配置文件,根据配置内容注册 Spring Bean
3、CasClientConfiguration
配置类中做了以下几件事:
casAuthenticationFilter()
创建了 认证过滤器casValidationFilter()
创建了 验证票据过滤器casHttpServletRequestWrapperFilter()
创建了请求对象的包装类casAssertionThreadLocalFilter()
创建了将Assertion
放到ThreadLocal
的过滤器,对于获取不到HttpRequest
请求对象的情况这很有用casSingleSignOutFilter()
创建了单点登出的过滤器casSingleSignOutListener()
创建单点登出的Listener,用于监听登出事件,清理内存中单点登录会话缓存SpringSecurityAssertionAutoConfiguration
兼容Spring Security的配置类
其中对于单点登录最重要的是 casAuthenticationFilter()
、casValidationFilter()
这两个方法,另外以上几个方法创建的对象类都在 cas-client-core.jar
,也就是说可以只引这一个包,然后自行配置。
有了自动配置我们再来看手动配置就比较简单了。
手动配置demo (服务B)
刚才也说了 cas-client-core.jar
是CAS客户端的核心依赖,必须引用!
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>${cas.client.version}</version>
</dependency>
然后就是编写配置类 com.hellxz.cas.Config.java
,使用 @Value
读取配置文件,生成最关键的2个过滤器 AuthenticationFilter
与 Cas30ProxyReceivingTicketValidationFilter
,为便于获取用户名配置了 HttpServletRequestWrapperFilter
过滤器,相当于自动配置demo的配置类简化版,如此而已。
至于为什么用
Cas30ProxyReceivingTicketValidationFilter
,AbstractTicketValidationFilter
是个抽象类,具体用哪个实现根据协议需要选择就可以了,更多配置参考官方客户端源码仓库 https://github.com/apereo/java-cas-client
总结
根据本次 集成 CAS 单点登录代码的编写与求证,验证了上篇文章 CAS 单点登录的流程,相信大家对CAS更加了解了。
由于行文紧促,可能出现错误与遗漏,还请大家多多包涵,评论指出,感激!
本文同步于本人博客园(hellxz.cnblogs.com) 与 CSDN(https://blog.csdn.net/u012586326),禁止转载。
CAS学习笔记三:SpringBoot自动配置与手动配置过滤器方式集成CAS客户端的更多相关文章
- 【转】SpringBoot学习笔记(7) SpringBoot整合Dubbo(使用yml配置)
http://blog.csdn.net/a67474506/article/details/61640548 Dubbo是什么东西我这里就不详细介绍了,自己可以去谷歌 SpringBoot整合Dub ...
- SpringBoot学习笔记(3)----SpringBoot的profile多环境配置
在实际的应用开发中,可能会需要不同配置文件来支撑程序的运行,如开发,测试,预生产,生产环境等,程序在不同的环境下可能需要不同的配置,如不同数据源等,如果每次在不同的环境下都要去修改配置文件就会闲得不合 ...
- MyBatis学习笔记(三)——优化MyBatis配置文件中的配置
转自孤傲苍狼的博客:http://www.cnblogs.com/xdp-gacl/p/4264301.html 一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的 ...
- CAS学习笔记五:SpringBoot自动/手动配置方式集成CAS单点登出
本文目标 基于SpringBoot + Maven 分别使用自动配置与手动配置过滤器方式实现CAS客户端登出及单点登出. 本文基于<CAS学习笔记三:SpringBoot自动/手动配置方式集成C ...
- 源码学习系列之SpringBoot自动配置(篇一)
源码学习系列之SpringBoot自动配置源码学习(篇一) ok,本博客尝试跟一下Springboot的自动配置源码,做一下笔记记录,自动配置是Springboot的一个很关键的特性,也容易被忽略的属 ...
- 源码学习系列之SpringBoot自动配置(篇二)
源码学习系列之SpringBoot自动配置(篇二)之HttpEncodingAutoConfiguration 源码分析 继上一篇博客源码学习系列之SpringBoot自动配置(篇一)之后,本博客继续 ...
- ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心
作者:Grey 原文地址:ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心 前置知识 完成ZooKeeper集群搭建以及熟悉ZooKeeperAPI基本使用 需求 很多程序往 ...
- VSTO学习笔记(三) 开发Office 2010 64位COM加载项
原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...
- [Firefly引擎][学习笔记三][已完结]所需模块封装
原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读: 笔记三主要就是各个模块的封装了,这里贴 ...
随机推荐
- 【Linux】【Shell】【Basic】流程控制
1. 选择执行: 1.1. if 单分支的if语句: if 测试条件 then 代码分支 fi 双分支的if语句: if 测试条件; then 条件为真时执行的分支 else 条件为假时执行的分支 f ...
- redis的总结笔记
# Redis 1. 概念: redis是一款高性能的NOSQL系列的非关系型数据库 1.1.什么是NOSQL NoSQL(NoSQL = Not Only ...
- JSP中session、cookie和application的使用
一.session (单用户使用) 1.用处:注册成功后自动登录,登录后记住用户状态等 使用会话对象session实现,一次会话就是一次浏览器和服务器之间的通话,会话可以在多次请求中保存和使用数据. ...
- InnoDB学习(三)之BinLog
BinLog又称为二进制日志,是MySQL服务层的数据日志,MySQL所有的存储引擎都支持BinLog.BinLog记录了MySQL中的数据更新和可能导致数据更新的事件,可以用于主从复制或数据恢复.本 ...
- 1888-jerry99的数列--factorial
1 #define _CRT_SECURE_NO_WARNINGS 1//jerry99的数列 2 #include<bits/stdc++.h> 3 int prime[40000] = ...
- Linux 目录结构及详细操作
目录 Linux 目录结构及详细操作 目录结构 目录结构的特点 目录结构挂载 目录结构发展 关闭selinux(了解) 重要目录说明(etc目录说明) 1.网卡配置文件 2.解析配置文件 3.主机名称 ...
- <转>Android多线程总结
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://yuchen.blog.51cto.com/2739238/593019 --An ...
- 简单的理解 Object.defineProperty()
Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性. Object.defineProperty(obj,prop,descriptor ...
- [BUUCTF]REVERSE——[WUSTCTF2020]level1
[WUSTCTF2020]level1 附件 步骤: 下载下来的附件有两个,output.txt里是一堆数字 64位ida打开第一个附件,检索字符串,发现了flag字样 双击跟进,ctrl+x交叉引用 ...
- MySQL 的日志:binlog
前言:binlog 用于记录数据库执行写入性操作的日志信息,以二进制的形式保留在磁盘中.它是由 Server 层进行记录的,使用任何存储引擎都会产生 binlog. 实验准备 我们通过 Docker ...