一、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客户端主要提供的是业务支持,我们在使用的时候更多是通过cas服务端来做认证支持。这里主要讲的是如何搭建cas客户端,配置的东西其实是通过spring的security来进行过滤。然后达到登录的目的,认证中主要是通过Ticket的票据进行认证的,当用户登录成功。会获取到登录的username,然后做进一步处理。

  四、服务端的部署参考:https://www.cnblogs.com/ll409546297/p/10410972.html

  五、客户端的搭建(这里服务端采用的https的方式)

  1)需要的依赖包

  <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
</dependency>
</dependencies>
  <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

  说明:下面这个依赖包主要是用于配置

  2)目录结构

  

  3)cas的参数配置(cas.properties、CasProperties)

cas.clientUrl=http://localhost:${server.port}
cas.clientLogin=/login
cas.clientLogout=/logout
cas.serverUrl=https://www.casserver.com:8443/cas
cas.serverLogin=/login
cas.serverLogout=/logout
cas.trustStorePath=cas/cas.keystore
cas.trustStorePassword=changeit
@PropertySource(value = "classpath:config/cas.properties")
@ConfigurationProperties(prefix = "cas")
public class CasProperties { //客户端url(本机)
private String clientUrl;
//登录接口
private String clientLogin;
//登出接口
private String clientLogout;
//服务端url
private String serverUrl;
//登录接口
private String serverLogin;
//登出接口
private String serverLogout;
//证书密匙路径
private String trustStorePath;
//密码
private String trustStorePassword; public String getClientUrl() {
return clientUrl;
} public void setClientUrl(String clientUrl) {
this.clientUrl = clientUrl;
} public String getClientLogin() {
return clientLogin;
} public void setClientLogin(String clientLogin) {
this.clientLogin = clientLogin;
} public String getClientLogout() {
return clientLogout;
} public void setClientLogout(String clientLogout) {
this.clientLogout = clientLogout;
} public String getServerUrl() {
return serverUrl;
} public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl;
} public String getServerLogin() {
return serverLogin;
} public void setServerLogin(String serverLogin) {
this.serverLogin = serverLogin;
} public String getServerLogout() {
return serverLogout;
} public void setServerLogout(String serverLogout) {
this.serverLogout = serverLogout;
} public String getTrustStorePath() {
return trustStorePath;
} public void setTrustStorePath(String trustStorePath) {
this.trustStorePath = trustStorePath;
} public String getTrustStorePassword() {
return trustStorePassword;
} public void setTrustStorePassword(String trustStorePassword) {
this.trustStorePassword = trustStorePassword;
}
}

  说明:1、trustStorePath:这个主要使用的服务器上面生成的cas.keystore密钥、在服务器搭建中我们生成了cas.keystore、域名改成www.casserver.com。目的不支持直接使用IP。

     本地修改hosts:C:\Windows\System32\drivers\etc\hosts

       

     

    2、cas.keystore:服务器生成密钥,tomcat进行部署,https访问时需要的私密密钥

    3、当然可以不使用cas.keystore,通过服务器上面生成的cas.crt证书然后客户端的jdk也是可以验证通过的。

keytool -import -keystore "E:\Java\jdk1.8.0_192\jre\lib\security\cacerts" -file cas.crt -alias cas -storepass changeit

  4)cas相关配置(CasConfiguration、SecurityConfiguration)

@Configuration
@Import(CasProperties.class)
public class CasConfiguration { //cas相关参数
@Autowired
private CasProperties casProperties; //客户端的服务配置,主要用于跳转
@Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
//该项目的登录地址
serviceProperties.setService(casProperties.getClientUrl() + casProperties.getClientLogin());
serviceProperties.setAuthenticateAllArtifacts(true);
return serviceProperties;
} //cas认证点
@Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
//cas的登录地址
casAuthenticationEntryPoint.setLoginUrl(casProperties.getServerUrl() + casProperties.getServerLogin());
//入口
casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
return casAuthenticationEntryPoint;
} //票据
@Bean
public Cas30ServiceTicketValidator cas30ServiceTicketValidator() {
return new Cas30ServiceTicketValidator(casProperties.getServerUrl());
} //认证支持
@Bean
public CasAuthenticationProvider casAuthenticationProvider(AuthDetailsService authDetailsService) {
CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
casAuthenticationProvider.setKey("client1");
casAuthenticationProvider.setServiceProperties(serviceProperties());
casAuthenticationProvider.setTicketValidator(cas30ServiceTicketValidator());
//本地登录后的操作,走security体系
casAuthenticationProvider.setUserDetailsService(authDetailsService);
//这里也可以使用setAuthenticationUserDetailsService管理
//casAuthenticationProvider.setAuthenticationUserDetailsService();
return casAuthenticationProvider;
} //单点登录过滤
@Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
singleSignOutFilter.setCasServerUrlPrefix(casProperties.getServerUrl());
singleSignOutFilter.setIgnoreInitConfiguration(true);
return singleSignOutFilter;
} //登出过滤
@Bean
public LogoutFilter logoutFilter() {
//重定向地址
String logoutRedirectPath = casProperties.getServerUrl() + casProperties.getServerLogout() + "?service=" + casProperties.getClientUrl();
LogoutFilter logoutFilter = new LogoutFilter(logoutRedirectPath, new SecurityContextLogoutHandler());
//登出接口
logoutFilter.setFilterProcessesUrl(casProperties.getServerLogout());
return logoutFilter;
} }
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
@Import(CasProperties.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { //认证
@Autowired
private CasAuthenticationProvider authenticationProvider; //认证点
@Autowired
private CasAuthenticationEntryPoint authenticationEntryPoint; //登出过滤
@Autowired
private LogoutFilter logoutFilter; //单点登出
@Autowired
private SingleSignOutFilter singleSignOutFilter; //cas配置
@Autowired
private CasProperties casProperties; @Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
//添加认证过滤(这里我遇到一个坑,如果通过注入方式加入,会出现循环依赖问题)
.addFilter(casAuthenticationFilter())
//登出过滤
.addFilterBefore(logoutFilter, LogoutFilter.class)
//单点登出过滤
.addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class);
} @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//认证方式
auth.authenticationProvider(authenticationProvider);
} @Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
//过滤器配置
CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
//使用security的认证管理
casAuthenticationFilter.setAuthenticationManager(authenticationManager());
//拦截登录接口
casAuthenticationFilter.setFilterProcessesUrl(casProperties.getClientLogin());
return casAuthenticationFilter;
}
}

  5)登录后的username处理(AuthDetailsService)

@Service
public class AuthDetailsService implements UserDetailsService { @Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username == null){
throw new UsernameNotFoundException("用户不存在!");
}
List<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<>();
simpleGrantedAuthorities.add(new SimpleGrantedAuthority("ADMIN"));
return new org.springframework.security.core.userdetails.User(username, username, simpleGrantedAuthorities);
}
}

  说明:这里只是简单处理,实际可以自己绑定用户处理

  6)https处理(CasIinitTask)

@Component
@Import(CasProperties.class)
public class CasIinitTask { @Autowired
private CasProperties casProperties; @PostConstruct
public void loadKeystore() throws IOException {
//如果使用https,则必须加入密钥
Assert.isTrue(!(casProperties.getServerUrl().startsWith("https") && casProperties.getTrustStorePath() == null),
"trustStorePath must not null to configuration https");
//密钥
if (!StringUtils.isEmpty(casProperties.getTrustStorePath())) {
Resource resource = new ClassPathResource(casProperties.getTrustStorePath());
System.setProperty("javax.net.ssl.trustStore", resource.getFile().getAbsolutePath());
}
//有可能密码的情况
if (StringUtils.isEmpty(casProperties.getTrustStorePassword())) {
System.setProperty("javax.net.ssl.trustStorePassword", casProperties.getTrustStorePassword());
}
}
}

  7)启动项目测试:

  六、源码:https://github.com/lilin409546297/springboot-cas

  七、这里只是简单的搭建过程,实际cas还需要做二次开发。相比于cas和oauth2我个人更加喜欢oauth2,个人看法。

springboot之cas客户端的更多相关文章

  1. CAS学习笔记三:SpringBoot自动配置与手动配置过滤器方式集成CAS客户端

    本文目标 基于SpringBoot + Maven 分别使用自动配置与手动配置过滤器方式集成CAS客户端. 需要提前搭建 CAS 服务端,参考 https://www.cnblogs.com/hell ...

  2. Springboot security cas整合方案-实践篇

    承接前文Springboot security cas整合方案-原理篇,请在理解原理的情况下再查看实践篇 maven环境 <dependency> <groupId>org.s ...

  3. Springboot security cas整合方案-原理篇

    前言:网络中关于Spring security整合cas的方案有很多例,对于Springboot security整合cas方案则比较少,且有些仿制下来运行也有些错误,所以博主在此篇详细的分析cas原 ...

  4. CAS5.3服务器搭建及SpringBoot整合CAS实现单点登录

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

  5. CAS客户端服务器端配置步骤

    来自我的个人网站:http://lkf.22web.org/ cas介绍: CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 ...

  6. 如何利用tomcat和cas实现单点登录(2):配置cas数据库验证和cas客户端配置

    接(1),上一篇主要讲述了tomcat和cas server端的部署. 接下来主要还有两个步骤. 注意:为了开启两个tomcat,要把直接配置的tomcat的环境变量取消!!!!!!!!!! 客户端配 ...

  7. 配置php的CAS客户端

    1.下载安装xmapp 2.开启Apache服务. 3.下载php的CAS客户端源码包(我使用的是CAS-1.2.0.tgz),解压到xmap的htdocs目录下(D:\xmapp\htdocs),进 ...

  8. cas sso单点登录系列2:cas客户端和cas服务端交互原理动画图解,cas协议终极分析

    转:http://blog.csdn.net/ae6623/article/details/8848107 1)PPT流程图:ppt下载:http://pan.baidu.com/s/1o7KIlom ...

  9. Springboot security cas源码陶冶-ExceptionTranslationFilter

    拦截关键的两个异常,对异常进行处理.主要应用异常则跳转至cas服务端登录页面 ExceptionTranslationFilter#doFilter-逻辑入口 具体操作逻辑如下 public void ...

随机推荐

  1. Allure 安装及使用

    linux下安装方法 Allure requires Java 8 or higher    npm install -g allure-commandline --save-dev (如果npm不能 ...

  2. Linux xargs命令详解

    find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部 xargs要处理的文件如果不是在结尾,需要加上 -i这个参数 xargs常见命令参数 args:xarg ...

  3. Alpha 冲刺报告(9/10)

    Alpha 冲刺报告(9/10) 队名:洛基小队 峻雄(组长) 已完成:角色属性功能的测试版 明日计划:准备α版本的ppt 剩余任务:尽量完成角色属性功能 困难:缺乏编程经验,很难自己独立完成编写,只 ...

  4. QT5.8连接Mysql提示QMYSQL driver not loaded

    我们都知道在QT5.8系列里已经带了Mysql的dll文件 驱动的名字为“qsqlmysql.dll”和“qsqlmysqld.dll” 但是按照网上的各种教程和博客基本都是错的,只有个别人是对的. ...

  5. Echarts使用小结

    还是先来简单的了解一下Echart是什么吧? ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前 ...

  6. 2015 ICL, Finals, Div. 2【ABFGJK】

    [题外话:我......不补了......] 2015 ICL, Finals, Div. 2:http://codeforces.com/gym/100637 G. #TheDress[水] (st ...

  7. No Spring WebApplicationInitializer types detected on classpath异常的解决

    1.问题描述,当配置成 时,通过地址栏访问默认路径的index.jsp报404错误,如果手动在浏览器输入“http://localhost:8080/index.jsp”,则出现源码文件,然后观察ec ...

  8. Python 3 与 Javascript escape 传输确保数据正确方法和中文乱码解决方案

    注意:现在已不推荐 escape 函数,推荐使用  encodeURIComponent 函数,其中方法更简单,只需进行URL解码即可. 当然了,如下文章解决方案一样可行. 前几天用Python的Bo ...

  9. java.sql.SQLException: Incorrect string value: '\xE5\xB0‘

    mysql插入中文字符报java.sql.SQLException: Incorrect string value: '\xE5\xB0‘ #原因:由于默认情况下,mysql的字符集是latin1(I ...

  10. c语言学习——安装

    作为颜控,选择了vs2019 工作组件选择c++,vs扩展开发. 默认安装就行了 安装成功,附图