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. RedisTemplate连接不释放、Redis断线不重连问题、Redis连接数高飙升

    使用RedisTemplate操作Redis数据,但遇到网络断线后不会重新连接 毫无头绪 一顿捣鼓 最终解决 整理如下 帮助更多的人 1.起因 使用RedisTemplate 配置 开启了事务 ena ...

  2. Blazor+Dapr+K8s微服务之服务调用

    1.1         Dapr环境配置 1.1.1        在开发机安装Docker Desktop并启用Kubernetes 安装过程略,安装好后效果如下:(左下角两个绿色指示Docker和 ...

  3. MATLAB—信号与系统中的应用

    文章目录 一. 理论知识 1.线性系统的响应 2.微分方程的解 Ⅰ.经典解 Ⅱ.完全响应 3.零输入响应 4.零状态响应 5.冲激响应 6.阶跃响应 7.卷积求零状态响应 二.连续信号的MATLAB描 ...

  4. Android WorkManager工作约束,延迟与查询工作

    WorkManager工作约束,延迟与查询工作 本文可能会混用"工作"与"任务"这两个词. 本文例子使用Kotlin 准备一个工作类(任务)UploadWork ...

  5. javaWeb之Maven

    为什么要学这个技术? 在JavaWeb开发中,需要使用大量的jar包 如何能够让一个工具自动帮我们导入和配置这个jar包 一.Maven项目架构管理工具 核心思想:约定大于配置 有约束,不要去违反 M ...

  6. noip18

    T1 来自cf原题 考场直接暴力枚举 \(A,B\),15pts. 正解: 首先时间的表达式,\(T=\frac{A}{a_{i}}+\frac{B}{b_{i}}\),然后以\(\frac{1}{a ...

  7. SpringCloud升级之路2020.0.x版-22.Spring Cloud LoadBalancer核心源码

    本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford 经过上一节的详细分 ...

  8. ASP.NET Core:依赖注入

    ASP.NET Core的底层设计支持和使用依赖注入.ASP.NET Core应用程序可以利用内置的框架服务将它们注入到启动类的方法中,并且应用程序服务能够配置注入.由ASP.NET Core提供的默 ...

  9. MVVMLight学习笔记(七)---Messenger使用

    一.概述 Messenger中文解释为信使的意思,顾名思义,在MvvmLight中,它的主要作用是用于View和ViewModel.ViewModel和ViewModel之间的通信. 考虑以下场景: ...

  10. C语言之----面向对象的方法实现链表的操作

    1 /* 2 * 详细运行过程: 本程序实现的是对链表的简单的操作,即链表的增 删 改 查 销毁 初始化 3 * 运用面向对象的思想,实现一个类op,op中包括了所有的链表操作方法 4 * 其他的程序 ...