跨域分布式系统单点登录的实现(CAS单点登录)
1. 概述
上一次我们聊了一下《使用Redis实现分布式会话》,原理就是使用 客户端Cookie + Redis 的方式来验证用户是否登录。
如果分布式系统中,只是对Tomcat做了负载均衡,或者所有的子系统都在同一个二级域名下,则 客户端Cookie + Redis 的方式是可以支持验证用户是否登录的。
如果分布式系统中包含了不同域名的子系统,之前的 客户端Cookie + Redis 的方式就不支持了,因为二级域名不同,Cookie无法共享。
例如:浏览器在子系统A的二级域名中保存了Cookie,在访问子系统B时,无法从Cookie中拿到数据,因此没有依据判断用户是否登录。
此时我们就需要引入CAS(中央认证服务),让CAS帮助我们实现跨域单点登录。
今天我们就来聊聊这个跨域分布式系统单点登录的实现。
2. 场景说明
子系统A域名:www.a.com
子系统B域名:www.b.com
CAS系统域名:www.cas.com
当子系统A和子系统B都未登录,则客户端请求时需要登录。
当客户端请求子系统A触发了登录,且登录成功,则客户端再请求子系统B时,不需要登录,可直接访问。
3.概念说明
全局票据:一个全局唯一的uuid,存放在域名为 .cas.com 的 Cookie 中,是用户已登录的标识。
临时票据:一个全局唯一的uuid,存放在Redis中,有过期时限,用于验证用户的身份。
4. 跨域单点登录的实现逻辑
4.1 用户访问子系统A
用户访问子系统A的页面,子系统A的页面请求子系统A的后台接口,子系统A后台检查当前系统的Cookie中是否存在用户脱敏信息。
因为从未登录过,所以Cookie中是不存在用户脱敏信息的,子系统A后台再检查参数中是否包含临时票据,此时是没有的,因此子系统A后台返回未登录给客户端。
客户端将当前子系统A页面的 url 作为参数,重定向到CAS系统的登录页面。
4.2 用户在CAS系统登录
重定向到CAS系统的登录页,登录页首先判断客户端在CAS系统的Cookie中,是否存在全局票据。
因为没有登录过,所以在CAS系统的Cookie中不存在全局票据,用户需要填写用户名、密码进行登录。
用户在CAS系统的登录页面,填写用户名、密码后,提交登录。
CAS系统后台,校验用户名、密码,通过后,生成一个全局唯一的 uuid,作为全局票据。
将全局票据存储在域名为 .cas.com 的 Cookie 中。
以全局票据为 key,用户ID 为 value,存到 Redis 中。
以用户ID为 key,用户信息为 value,存到 Redis 中。
再生成一个 uuid 作为临时票据,以临时票据为 key,临时票据为 value,存储到Redis中,5分钟过期。
CAS系统返回临时票据给客户端。
客户端将页面重定向回子系统A的页面,临时票据作为参数携带。
4.3 再次访问子系统A
页面被重定向回子系统A的页面。
子系统A携带临时票据访问子系统A的后台接口,后台检查当前系统的Cookie中是否存在用户脱敏信息,仍然是不存在。
后台检查参数中是否包含临时票据,临时票据是存在的,子系统A的后台调用CAS后台的用户身份验证接口,以临时票据作为参数。
CAS用户身份验证接口,以临时票据为key,从redis中获取value,value不为空,则验证成功。
从CAS系统的Cookie中得到全局票据,以全局票据为key,从Redis中得到用户ID,然后从redis中得到用户信息,返给子系统A的后台。
子系统A拿到用户信息后,将其脱敏,存储在域名为 .a.com 的 Cookie 中,然后完成接口逻辑。
子系统A再次访问其他接口时,后台检查当前系统的Cookie中是否存在用户脱敏信息,此时是存在的。
后台使用用户脱敏信息中的用户ID到Redis中获取完整的用户信息,然后完成接口逻辑。
如果Redis中用户信息不存在,则表示用户已注销登录,则返回未登录。
4.4 用户访问子系统B
用户访问子系统B,子系统B后台检查当前系统的Cookie中是否存在用户脱敏信息,不存在。然后检查是否存在临时票据,也不存在。返回未登录。
重定向到CAS系统的登录页面,子系统B页面的 url 作为参数。
CAS系统后台,判断在CAS系统的Cookie中,是否存在全局票据,此时是存在的,因为使用的是同一个客户端。
CAS系统后台生成一个uuid作为临时票据,以临时票据为 key,临时票据为 value,存储到Redis中,5分钟过期。
CAS系统返回临时票据给客户端。
客户端将页面重定向回子系统B的页面,临时票据作为参数携带。
子系统B携带临时票据访问子系统B的后台接口,后台检查当前系统的Cookie中是否存在用户脱敏信息,仍然是不存在。
后台检查参数中是否包含临时票据,临时票据是存在的,子系统B的后台调用CAS后台的用户身份验证接口,以临时票据作为参数。
CAS用户身份验证接口,以临时票据为key,从redis中获取value,value不为空,则验证成功。
从CAS系统的Cookie中得到全局票据,以全局票据为key,从Redis中得到用户ID,然后从redis中得到用户信息,返给子系统B的后台。
子系统B拿到用户信息后,将其脱敏,存储在域名为 .b.com 的 Cookie 中,然后完成接口逻辑。
这样一来,用户无感知的访问了子系统B,不需要再次输入用户名、密码去登录。
4.5 用户注销
用户注销时,首先清空当前子系统中用户脱敏信息的Cookie。
然后访问CAS系统的用户注销接口。
CAS系统,从Cookie中拿到全局票据,根据全局票据从Redis中得到用户ID。
删除Cookie中的全局票据。
从Redis中删除 key 为 全局票据 的数据。
从Redis中删除 key 为 用户ID 的数据 。
4.6 总结
这里用了一个小技巧,a.com 和 b.com 的 Cookie 无法共享,因此就在一个公共的 cas.com 中去存Cookie,然后再做一次身份校验就可以了。
5. 综述
今天简单聊了一下跨域分布式系统单点登录的实现,希望能对大家的工作有所帮助。
欢迎大家帮忙点赞、评论、加关注 :)
关注追风人聊Java,每天更新Java干货。
跨域分布式系统单点登录的实现(CAS单点登录)的更多相关文章
- SSO单点登录一:cas单点登录防止登出退出后刷新后退ticket失效报500错,也有退出后直接重新登录报票根验证错误
问题1: 我登录了client2,又登录了client3,现在我把client2退出了,在client3里面我F5刷新了一下,结果页面报错: 未能够识别出目标 'ST-41-2VcnVMguCDWJX ...
- 基于CAS的SSO单点登录-实现ajax跨域访问的自动登录(也相当于超时重连)
先补课,以下网址可以把CAS环境搭起来. [JA-SIG CAS服务环境搭建]http://linliangyi2007.iteye.com/blog/165307 [JA-SIG CAS业务架构介绍 ...
- vue+springboot前后端分离实现单点登录跨域问题处理
最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的.因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统.那就意味着做单点登 ...
- java:sso(单点登录(single sign on),jsp文件动静态导入方式,session跨域)
1.jsp文件导入: 2.session跨域: 3.sso(单点登录(single sign on): sso Maven Webapp: LoginController.java: package ...
- 使用 P3P 规范让 IE 跨域接受第三方 cookie
前两天帮同事处理一个 js 跨域问题,使用 jsonp 跨域提交用户名密码请求,实现自动登录第三方网站,即 SSO(single-sign-on) 单点登录,一处登录处处登录.在 Chrome 下没问 ...
- 跨域post 及 使用token防止csrf 攻击
环境: 后台使用的python - flask 前台使用angular框架 1.一个跨域post的样例: 跨域post有多种实现方式: 1.CORS:http://blog.csdn.net/hfah ...
- 使用Cookie实现跨域单点登录的原理
对于构建分布式系统来说业务功能的物理部署会随着新业务模块的增加而增加或改变物理部署的位置.而每个用户都有统一的帐号作为我们登录系统时的一个认证.当新业务或子系统部署在不同的物理机上,我们去访问不同的业 ...
- 可跨域的单点登录(SSO)实现方案【附.net代码】
SSO简介 定义: 传统的单站点登录访问授权机制是:登录成功后将用户信息保存在session中,sessionId保存在cookie中,每次访问需要登录访问的资源(url)时判断当前session是否 ...
- 偷懒小工具 - SSO单点登录通用类(可跨域)
写在前面的话 上次发布过一篇同样标题的文章.但是因为跨域方面做得不太理想.我进行了修改,并重新分享给大家. 如果这篇文章对您有所帮助,请您点击一下推荐.以便有动力分享出更多的"偷懒小工具&q ...
随机推荐
- Crash course statistics
Crash course statistics 01什么是统计学 描述性统计(Descriptive statistics) 推理统计可以得出之外的,基于"样本"的推论统计学来估计 ...
- rancher v1.6.29部署K8s
1. 前提:上一文中,已部署好单节点Rancher v1.6.29 2. 在Rancher中,添加环境模板 修改k8s设置参数 参数修改明细: Private Registry for Add-Ons ...
- Note about Cobertura
Workflow of Unit Test without Cobertura compile source code; compile test code; run unit test; Workf ...
- Redis-01-基础
基本概念 1 基本概念 redis是一个开源的.使用C语言编写的.支持网络交互的.可基于内存也可持久化的Key-Value数据库(非关系性数据库) redis运维的责任 1.保证服务不挂 2.备份数据 ...
- 寻找写代码感觉(二)之 Spring Boot 项目属性配置
一.前言 写代码就和恋爱一样,有反馈就要趁热打铁,搞完了项目搭建,接下来就来搞搞项目配置. 二.IDEA设置 1.编码配置 这里所说的就是代码的编码格式,你可以不设置,但是可能要面临的是,很多未知的麻 ...
- 黑马JVM教程——自学笔记(二)
三.垃圾回收 3.1.如何判断对象可以回收 3.1.1 引用计数法 弊端:循环引用时,两个对象的计数都为1,导致两个对象都无法被释放 3.1.2 可达性分析算法 JVM中的垃圾回收器通过可达性分析来探 ...
- docker加速器,设置cdn
添加加速器 vim /etc/docker/daemon.json 添加如下内容 { "registry-mirrors": ["https://registry.doc ...
- 1、Task的优势
1.Task的优势 ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便.比如: ◆ ThreadPool不支持线程的取消.完成.失败通知等交互性 ...
- Hibernate之持久化对象
时间:2017-1-19 23:00 --Hibernate持久化类的状态1.持久化类:就是一个实体类与数据库建立了映射.2.Hibernate为了方便管理持久化类,将持久化类分为了三种状态: ...
- ProjectEuler 007题
题目:By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is ...