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单点登录)的更多相关文章

  1. SSO单点登录一:cas单点登录防止登出退出后刷新后退ticket失效报500错,也有退出后直接重新登录报票根验证错误

    问题1: 我登录了client2,又登录了client3,现在我把client2退出了,在client3里面我F5刷新了一下,结果页面报错: 未能够识别出目标 'ST-41-2VcnVMguCDWJX ...

  2. 基于CAS的SSO单点登录-实现ajax跨域访问的自动登录(也相当于超时重连)

    先补课,以下网址可以把CAS环境搭起来. [JA-SIG CAS服务环境搭建]http://linliangyi2007.iteye.com/blog/165307 [JA-SIG CAS业务架构介绍 ...

  3. vue+springboot前后端分离实现单点登录跨域问题处理

    最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的.因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统.那就意味着做单点登 ...

  4. java:sso(单点登录(single sign on),jsp文件动静态导入方式,session跨域)

    1.jsp文件导入: 2.session跨域: 3.sso(单点登录(single sign on): sso Maven Webapp: LoginController.java: package ...

  5. 使用 P3P 规范让 IE 跨域接受第三方 cookie

    前两天帮同事处理一个 js 跨域问题,使用 jsonp 跨域提交用户名密码请求,实现自动登录第三方网站,即 SSO(single-sign-on) 单点登录,一处登录处处登录.在 Chrome 下没问 ...

  6. 跨域post 及 使用token防止csrf 攻击

    环境: 后台使用的python - flask 前台使用angular框架 1.一个跨域post的样例: 跨域post有多种实现方式: 1.CORS:http://blog.csdn.net/hfah ...

  7. 使用Cookie实现跨域单点登录的原理

    对于构建分布式系统来说业务功能的物理部署会随着新业务模块的增加而增加或改变物理部署的位置.而每个用户都有统一的帐号作为我们登录系统时的一个认证.当新业务或子系统部署在不同的物理机上,我们去访问不同的业 ...

  8. 可跨域的单点登录(SSO)实现方案【附.net代码】

    SSO简介 定义: 传统的单站点登录访问授权机制是:登录成功后将用户信息保存在session中,sessionId保存在cookie中,每次访问需要登录访问的资源(url)时判断当前session是否 ...

  9. 偷懒小工具 - SSO单点登录通用类(可跨域)

    写在前面的话 上次发布过一篇同样标题的文章.但是因为跨域方面做得不太理想.我进行了修改,并重新分享给大家. 如果这篇文章对您有所帮助,请您点击一下推荐.以便有动力分享出更多的"偷懒小工具&q ...

随机推荐

  1. 字节跳动已经10万人了?渣本双非Android程序员怎么上车?

    字节跳动已经 10 万人了? 是的,在 2020 年字节跳动的员工总数从 6 万蹿到 10 万,平均每个工作日就有 150 人在办理入职,加入字节跳动全球超过 240 个办公点. 更有统计,在总部北京 ...

  2. 1.9 货仓选址问题——Python

    题目描述 在一条数轴上有 N 家商店,它们的坐标分别为 A1~AN. 现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品. 为了提高效率,求把货仓建在何处,可以使得货仓到每家商店 ...

  3. [源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampler

    [源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampler 目录 [源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampl ...

  4. 痞子衡嵌入式:在IAR开发环境下将关键函数重定向到RAM中执行的三种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将关键函数重定向到RAM中执行的三种方法. 嵌入式项目里应用程序代码正常是放在 Flash 中执行的,但有时候也需要将 ...

  5. Compile Java Codes in Linux Shell instead of Ant Script

    The following is frequently used ant script, compile some java source codes with a libary path, then ...

  6. 解决tomcat7中request会对中文重新编码,导致后台接收到为encode编码后参数问题

    package xxx; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.ut ...

  7. Mysql的分区表

    概论: 分区表一般用作Mysql库表的水平切割(也就是常说的mysql性能优化的几种通用手法"读写分离.分库分表"中的一种),适用于单表的数据量可能很大的场景.因为分区表可以将一个 ...

  8. kubebuilder实战之一:准备工作kubebuilder实战之一:准备工作

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  9. NOIP 模拟 $20\; \rm z$

    题解 很考验思维的一道题 对于不同的任务点,发现如果 \(x_{i-1}<x_i<x_{i+1}\) 或 \(x_{i-1}>x_i>x_{i+1}\) 那么 \(x_i\) ...

  10. 备战秋招之十大排序——O(n)级排序算法

    时间复杂度O(n)级排序算法 九.计数排序 前文说到,19591959 年 77 月,希尔排序通过交换非相邻元素,打破了 O(n^2)的魔咒,使得排序算法的时间复杂度降到了 O(nlog n) 级,此 ...