CAS单点登录原理及改造

article/2025/9/4 0:26:53

      CAS是由耶鲁大学开发的单点登录系统,其核心的知识点包括以下几个概念:

      1) TGT: 票据,或称大令牌,在登录成功之后生成,其中包含了用户信息

      2) TGC: TGT的key,TGT存储在session中,TGC以cookie形式保存在浏览器中,当再次访问CAS时,会根据TGC去查找对应的TGT

      3) ST: 小令牌,由TGT生成,默认使用一次就失效

      业务系统前后端分离情况下基于CAS完成单点登录的时序图如图所示:

       假设业务系统域名为mail.test.com,cas服务的域名为cas.test.com

       1) 在浏览器首先打开mail.test.com,由于cookie以及storage中都没有token信息,故跳转到CAS服务中,url为cas.test.com/login?service=mail.test.com

       2) CAS服务返回登录页面,用户输入用户名密码进行登录

       3) CAS校验用户名密码,校验成功,则根据用户信息生成TGT、TGC,并将TGC写入到浏览器的cookie中,同时根据TGT生成ST,再重定向到mail.test.com?ticket=ST

       4) 浏览器再次接收到mail.test.com请求,由于此时携带了ticket,故调用后端服务接口

       5) 后端服务收到ticket,调用cas.test.com/p3/seviceValidate校验ticket,若校验通过,则返回的校验信息中携带了用户信息;根据用户信息生成token返回给前端

       6) 前端将token保存到浏览器的cookie或storage中

       这里需要注意的时CAS只是进行身份认证,token的生成需要业务系统自己实现

       假设此时另一个业务系统bussiness.test.com也进入了CAS,在浏览器首次打开bussiness.test.com时,由于当前域名下没有存储token,则也会跳转到CAS中,url为cas.test.com/login?service=bussiness.test.com;此时CAS域名下的cookie中存储了TGC,则CAS服务根据TGC可以查找到TGT,再根据TGT生成ST,重定向到bussiness.test.com?ticket=ST,后面的流程与前述相同。

  

       CAS默认是通过用户名密码登录,在业务需要场景下,需要将登录方式修改为基于短信验证码登录,为此需要对CAS进行二次开发。

       CAS源码中使用UsernamePasswordCredentail类来实现登录凭证,在此定义一个新的类来实现验证码登录凭证:

public class PhoneCaptchaCredential implements Credential {private static final long serialVersionUID = -1616013347177519641L;@Size(min = 1, message = "required.phone")private String phone;@Size(min = 1, message = "required.captcha")private String captcha;@Overridepublic String getId() {return this.phone;}@Generatedpublic PhoneCaptchaCredential() {}@Generatedpublic PhoneCaptchaCredential(String phone, String captcha) {this.phone = phone;this.captcha = captcha;}
}

       重写DefaultLoginWebflowConfigurer.createRememberMeAuthnWebflowConfig的逻辑:

@Overrideprotected void createRememberMeAuthnWebflowConfig(Flow flow) {if (casProperties.getTicket().getTgt().getRememberMe().isEnabled()) {createFlowVariable(flow, CasWebflowConstants.VAR_ID_CREDENTIAL, PhoneCaptchaCredential.class);final ViewState state = getState(flow, CasWebflowConstants.STATE_ID_VIEW_LOGIN_FORM, ViewState.class);final BinderConfiguration cfg = getViewStateBinderConfiguration(state);cfg.addBinding(new BinderConfiguration.Binding("phone", null, false));cfg.addBinding(new BinderConfiguration.Binding("captcha", null, true));} else {createFlowVariable(flow, CasWebflowConstants.VAR_ID_CREDENTIAL, UsernamePasswordCredential.class);}}

     在配置文件中需添加 cas.ticket.tgt.rememberMe.enabled=true

     自定义handler完成认证流程:

public class CasAuthenticationHandler extends AbstractPreAndPostProcessingAuthenticationHandler {private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CasAuthenticationHandler.class);public CasAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) {super(name, servicesManager, principalFactory, order);}private AuthenticationHandlerExecutionResult doPhoneAuthentication(PhoneCaptchaCredential phoneCaptchaCredential, JdbcTemplate jdbcTemplate)throws GeneralSecurityException {String phone = phoneCaptchaCredential.getPhone();String captcha = phoneCaptchaCredential.getCaptcha();JedisPool pool = new JedisPool(new JedisPoolConfig(), "xx.xx.xx.xx", 6379);Jedis redis = pool.getResource();String redisCode = redis.get("CAS-" + phone);if (null == redisCode) {logger.error("验证码已过期");throw new AccountException("验证码已过期!");}if (!StringUtils.equals(redisCode, captcha)) {logger.error("验证码错误");throw new AccountException("验证码错误!");}String sql = "select * from cas_user where phone = ? and status = 0";User info = (User) jdbcTemplate.queryForObject(sql, new Object[]{phone}, new BeanPropertyRowMapper(User.class));if (info == null) {logger.error("用户不存在或账户已锁定");throw new AccountException("用户不存在或账户已锁定");}final List<MessageDescriptor> list = new ArrayList<>();/**可自定义返回给客户端的多个属性信息**/HashMap<String, Object> returnInfo = new HashMap<>();returnInfo.put("status", info.getStatus());returnInfo.put("deleted", info.getDeleted());returnInfo.put("name", info.getName());returnInfo.put("sex", info.getSex());returnInfo.put("age", info.getAge());return createHandlerResult(phoneCaptchaCredential,this.principalFactory.createPrincipal(info.getUsername(), returnInfo), list);}@Overrideprotected AuthenticationHandlerExecutionResult doAuthentication(Credential credential) throws GeneralSecurityException, PreventedException {// 先构建数据库驱动连接池DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql://xx.xx.xx.xx:3306/test");dataSource.setUsername("xxxx");dataSource.setPassword("xxxxxx");return doPhoneAuthentication((PhoneCaptchaCredential) credential, jdbcTemplate);}@Overridepublic boolean supports(Credential credential) {return credential instanceof PhoneCaptchaCredential;}
}

     最后定义AuthConfig:

@Configuration("MyAuthConfig")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class MyAuthConfig implements AuthenticationEventExecutionPlanConfigurer {@Autowiredprivate CasConfigurationProperties casProperties;@Autowired@Qualifier("servicesManager")private ServicesManager servicesManager;@Autowired@Qualifier("loginFlowRegistry")private FlowDefinitionRegistry loginFlowRegistry;@Autowiredprivate ApplicationContext applicationContext;@Autowiredprivate FlowBuilderServices flowBuilderServices;@Beanpublic PrePostAuthenticationHandler myAuthenticationHandler() {return new CasAuthenticationHandler(CasAuthenticationHandler.class.getName(),servicesManager, new DefaultPrincipalFactory(), 1);}@Overridepublic void configureAuthenticationExecutionPlan(AuthenticationEventExecutionPlan plan) {plan.registerAuthenticationHandler(myAuthenticationHandler());}@Bean("defaultLoginWebflowConfigurer")public CasWebflowConfigurer defaultLoginWebflowConfigurer() {DefaultCaptchaWebflowConfigurer c = new DefaultCaptchaWebflowConfigurer(flowBuilderServices, loginFlowRegistry, applicationContext, casProperties);c.initialize();return c;}
}

  修改templates中html文件,完成页面适配修改:

  


http://chatgpt.dhexx.cn/article/mKm1cjIf.shtml

相关文章

SSO单点登录原理详解(从入门到精通)

本文主要对SSO单点登录与CAS、OAuth2.0两种授权协议的关系和原理进行详细说明。 1. 基础概念 SSO单点登录&#xff08;Single sign-on&#xff09; 所谓单点登录就是在多个应用系统中&#xff0c;用户只需登录一次就可以访问所有相互信任的系统。 CAS 中央认证服务&#xf…

CAS单点登录的实现

这篇文章对CAS单点登录具体实现的一些步骤就行讲述&#xff0c;至于CAS单点登录的实现原理分析&#xff0c;请参看下面这篇文章&#xff1a;CAS单点登录原理分析(一) https://blog.csdn.net/qq_41258204/article/details/84036875 CAS 包含两个部分&#xff1a; CAS Server 和…

CAS单点登录原理解析

推荐阅读 1. SpringBoot 整合篇 2. 手写一套迷你版HTTP服务器 3. 记住&#xff1a;永远不要在MySQL中使用UTF-8 4. Springboot启动原理解析 1、基于Cookie的单点登录的回顾 基于Cookie的单点登录核心原理&#xff1a; 将用户名密码加密之后存于Cookie中&#xff0c;之后访…

CAS单点登录的实现(二)

这篇文章对CAS单点登录具体实现的一些步骤就行讲述&#xff0c;至于CAS单点登录的实现原理分析&#xff0c;请参看下面这篇文章&#xff1a; CAS单点登录原理分析(一) https://blog.csdn.net/qq_41258204/article/details/84036875 CAS 包含两个部分&#xff1a; CAS Server 和…

CAS单点登录系列之原理简单介绍

文章目录 一、 SSO简介1.1 单点登录定义1.2 单点登录角色1.3 单点登录分类 二、 CAS简介2.1 CAS简单定义2.2 CAS体系结构2.3 CAS原理 三、CAS服务端部署附录 一、 SSO简介 1.1 单点登录定义 单点登录(Single sign on)&#xff0c;英文名称缩写SSO&#xff0c;SSO的意思就是在…

CAS实现单点登录SSO执行原理探究(终于明白了)

一、不落俗套的开始 1、背景介绍 单点登录:Single Sign On,简称SSO,SSO使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 CAS框架:CAS(Central Authentication Service)是实现SSO单点登录的框架。 2、盗一张学习CAS绝大多都看过的图以及执…

CAS实现单点登录

1.简介 SSO单点登录 在多个相互信任的系统中&#xff0c;用户只需要登录一次就可以访问其他受信任的系统。 新浪微博与新浪博客是相互信任的应用系统。 *当用户首次访问新浪微博时&#xff0c;新浪微博识别到用户未登录&#xff0c;将请求重定向到认证中心&#xff0c;认证中心…

cas server + cas client 单点登录 原理介绍

CAS 介绍 CAS 是 Yale 大学发起的一个开源项目&#xff0c;旨在为 Web 应用系统提供一种可靠的单点登录方法&#xff0c;CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点&#xff1a; 开源的企业级单点登录解决方案。 CAS Server 为需要独立部署的 Web 应用…

CAS单点登录原理(包含详细流程,讲得很透彻,耐心看下去一定能看明白!)

转载地址 http://www.cnblogs.com/lihuidu/p/6495247.html 1、基于Cookie的单点登录的回顾 基于Cookie的单点登录核心原理&#xff1a; 将用户名密码加密之后存于Cookie中&#xff0c;之后访问网站时在过滤器&#xff08;filter&#xff09;中校验用户权限&#xff0c;如果没有…

CAS方式实现单点登录

单点登录&#xff0c;英文是 Single Sign On&#xff0c;缩写为 SSO。 多个站点(192.168.1.20X)共用一台认证授权服务器(192.168.1.110&#xff0c;用户数据库和认证授权模块共用)。用户经由其中任何一个站点(比如 192.168.1.201)登录后&#xff0c;可以免登录访问其他所有站点…

单点登录之CAS原理和实现

1.开源单点登录系统CAS入门 1.1 什么是单点登录 单点登录&#xff08;Single Sign On&#xff09;&#xff0c;简称为 SSO&#xff0c;是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中&#xff0c;用户只需要登录一次就可以访问所有相互信任的应用…

CAS单点登录原理分析(一)

一&#xff0c;业务分析 在分布式系统架构中&#xff0c;假设把上述的三个子系统部署在三个不同的服务器上。前提是用户登录之后才能访问这些子系统。那么使用传统方式&#xff0c;可能会存在这样的问题&#xff1a; 1.当访问用户中心&#xff0c;需要用户登录帐号 2.当访问购物…

cas单点登录原理与实现(整合springsecurity)

一、cas原理分析 SSO英文全称Single Sign On&#xff0c;单点登录。SSO是在多个应用系统中&#xff0c;用户只需要登录一次就可以访问所有相互信任的应用系统。CAS是一种基于http协议的B/S应用系统单点登录实现方案&#xff0c;认识CAS之前首先要熟悉http协议、Session与Cookie…

CAS 实现单点登录(SSO)原理

原地址&#xff1a;https://blog.csdn.net/hejingyuan6/article/details/44277023 一、概念&#xff1a;     单点登录&#xff08;Single Sign On&#xff09;&#xff1a;简称为SSO&#xff0c;是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中…

CAS单点登录原理

转载地址&#xff1a;转载博客 1、基于Cookie的单点登录的回顾 基于Cookie的单点登录核心原理&#xff1a; 将用户名密码加密之后存于Cookie中&#xff0c;之后访问网站时在过滤器&#xff08;filter&#xff09;中校验用户权限&#xff0c;如果没有权限则从Cookie中取出用户…

python iloc函数_如何使用python语言中pandas模块中的iloc方法

在python语言中,pandas模块中的iloc方法,可以截取矩阵,获取部分矩阵元素、行和列。下面利用实例说明iloc方法的用法,操作如下: 工具/原料 python pycharm 截图工具 方法/步骤 1 打开pycharm工具,新建python文件,导入numpy和pandas,调用DataFrame生成矩阵 2 保存…

python iloc和loc切片

文章目录 一、含正负号的下标二、loc和iloc1. 利用loc、iloc提取行数据2. 利用loc、iloc提取列数据3.利用loc、iloc提取指定行、指定列数据4.利用loc、iloc提取所有数据5.利用loc函数&#xff0c;根据某个数据来提取数据所在的行 一、含正负号的下标 正下标从0开始&#xff0c;…

Pandas之iloc、loc

除了最基本的筛选外&#xff0c;例&#xff1a;data[‘A’] 还有loc、iloc、ix&#xff08;已不推荐使用&#xff09; 我对它们的区分&#xff0c;说loc&#xff08;location&#xff09;&#xff0c;在教室里找不认识的同学的位置一样的&#xff0c;找人肯定要知道名字或者身…

iloc函数使用方法

iloc函数使用方法 iloc[ : , : ] 前面的冒号就是取行数&#xff0c;后面的冒号是取列数 左闭右开原则 举个例子来理解切片的概念。 animals[2&#xff1b;5] 其中2,5都是指的元素的索引&#xff0c;索引从0开始&#xff0c;表示从第3个元素到第四个元素&#xff08;前开后闭…