实现SSO单点登录的思考
关注 “Java艺术” 我们一起成长!
随着公司业务的发展,子系统越来越多,实现SSO
单点登录的需求就愈加迫切。
我们一些子系统中都有使用Redis
存储Session
,这最初是为了解决应用集群部署时的Session
共享问题,却也为应用之间共享Session提供了支持,但单靠应用之间共享Session
是无法实现单点登录的。
在单应用中,当用户登录系统后,用户的登录状态被存储在服务端的Session
中,并通过响应头的Cookie
字段将SessionId
传递给浏览器存储,后续请求服务端时,浏览器会自动在请求头加上Cookie
,所以才能保持用户的登录状态。
使用Redis
共享Session
,集群之间可以共享Session
的原理与服务重启后依然保持登录状态的原理相同。
在应用重启后,由于浏览器还是携带cookie
发起请求,如果Session
未过期,那么从Redis
获取到的Session
就能继续使用。
由此可见,虽然应用之间可通过Redis
共享Session
,但要求浏览器向每个应用发起请求都能带上相同Cookie
才能实现单点登录。
然浏览器却不支持不同域名之间Cookie
共享,服务端也不能操控客户端浏览器访问不同域名下的站点都带上相同的SessionId
。要实现单点登录我们只能另辟蹊径。
虽然浏览器不支持不同域名之间共享Cookie
,但同一个主域名的不同子域名应用间可通过配置Cookie
为主域名方式实现Cookie
共享,前提是所有子系统都共用一个主域名。这种方案可取也不可取,短期而言可取,长期而言不可取。
如果只是实现web
应用之间相互跳转,由用户在应用a
点击按钮跳转到应用b
,也可以这样实现:当用户在应用a
点击跳转应用b
时,在跳转链接上带上SessionId
,应用b
根据SessionId
读取用户信息再写入Session
。
先不讨论安全性如何,这种方式的弊端也很明显,用户不能直接在浏览器输入应用B
的域名跳转,而只能通过应用A
跳转到应用B
,要返回应用A
也只能从应用B
点击按钮跳转回应用A
。
虽然通过点击按钮方式实现应用之间互相跳转不是一个好的计策,但至少通过在跳转链接上携带SessionId
共享登录状态这个思路是可取的。
根据这个思路,我们是否可以实现不通过点击按钮方式也能让浏览器自动带上SessionId
呢?
可以,但要通过重定向实现。
当用户在系统A
登录后,直接在浏览器上修改域名访问系统B
时,系统B
检查到用户未登录后将请求重定向到系统A
,系统A
检查到请求从系统B
重定向过来,并且用户已经登录,那么可将SessionId
拼接到重定向链接上,再重定向回系统B
。系统B
获取到系统A
的SessionId
,然后根据SessionId
从Redis
查询用户信息,再写入系统B
的Session
中。如此就能实现自动携带SessionId
跳转。
只不过,这种方式要求每个系统都实现一遍这样的功能,并且每个系统也都要提供登录功能。
为了简化实现,以及后续的新系统不再重复实现登录功能,我们应该考虑将登录功能抽离为一个独立的应用,其它系统不再提供登录功能。
将登录功能抽离为独立应用之后,实现SSO
单点登录流程梳理如下:
将SSO
抽离为一个独立的应用,独立的域名,提供登录页面,要求其它应用不再提供登录页面,都必须通过SSO
登录。
其它应用在接收到请求时,首先根据session
判断是否已经登录了,如果未登录则重定向到SSO
登录页面,并且在重定向链接带上是哪个应用跳转过来的,当用户在SSO
登录成功后重定向回原来的应用。
浏览器重定向到SSO
登录页面时,浏览器会存储SSO
的cookie
,用户在SSO
登录成功后,SSO
存储用户的登录状态。SSO
生成一个token
,重定向回原应用,在重定向链接上带上token
。
原应用检查请求携带token
,这时需要访问SSO
验证token
并获取用户信息,SSO
验证成功后返回用户信息,原应用将用户信息存储到Session
中,验证成功后再重定向到首页。
如果用户此时通过在浏览器输入应用B
的域名访问应用B
,由于应用B
检查到Session
没有用户信息(未登录),于是重定向到SSO
应用。
因为用户在SSO
登录过了,重定向请求SSO
应用时浏览器会带上cookie
,所以SSO
应用发现用户已经登录,于是生成一个token
并重定向回应用B
。
应用B
接收重定向请求,从请求中获取到token
,接着访问sso
应用验证token
并获取用户信息,在获取用户信息成功后再写入Session
,最后重定向到首页。
根据梳理的流程,总结每个应用需要实现的功能:
SSO
应用:
提供登录功能,支持从哪个应用重定向过来,登录成功后就重定向回哪个应用去;
提供根据
token
获取当前登录用户信息的接口。
其它应用:
未登录则重定向跳转到
SSO
,在跳转链接上带上登录成功后重定向调用的接口;提供给SSO重定向调用的接口,用于接收SSO传递的token,根据token从SSO获取登录用户信息,将用户信息写入Session,最后重定向到前端首页。
在前后端分离的系统上实现这一流程并不容易,实际实现比本文描述的步骤还要多。
我们通过封装SDK
的方式,尽可能将繁琐的步骤封装起来,让其它应用对接SSO
时仅需要依赖一个jar
包,并添加少量的配置。
SDK
通过Servlet
提供的过滤器拦截所有请求:
1、如果请求是
“/checketSsoToken”
,则说明是用户在SSO
登录成功后(浏览器重定向)跳转过来的,并且会携带token
参数。此时SDK
需要请求SSO
检验token
,并将获取的用户信息写入Session
中,然后重定向到当前应用的前端首页。2、如果不是
“/checketSsoToken”
,则查看配置,判断当前请求是否不需要登录也可放行,如果是则放行,否则判断Session
中是否记录用户已经登录,如果未登录,则响应重定向,由前端跳转到SSO
登录。
由于前后端分离,前端通过ajax
请求接口,后端判断未登录响应重定向无法真正重定向,所以要求前端拦截所有请求的响应,如果响应头有重定向标志,应从请求头获取重定向链接,然后让浏览器重定向。
3、如果是退出登录请求,则先清除应用自身缓存的用户登录信息,再重定向到
SSO
退出登录。
实际实现的单点登录流程如下:
1、用户在浏览器中输入应用
A
的域名,要跳转到前端的index.html
页面;(nginx
反向代理配置实现)2、前端在首页调用一个后端接口,如获取菜单,触发校验登录(前端实现),未登录则拼接重定向链接,响应给前端,要求重定向到
SSO
登录页面(SDK
封装实现);3、用户在
SSO
登录成功后,由SSO
重定向调用应用A
的“/checketSsoToken”。此url
在应用A
重定向到SSO
登录时作为参数拼接在URL
后面,由后端提供,前端只负责重定向;(SSO
应用实现)4、应用
A
请求SSO
的校验token
接口,并将响应的用户信息写入session
,重定向回前端首页。(SDK
封装实现)
需要注意的是,假设SSO设置的session过期时间为一个小时,如果用户在SSO登录后跳转回应用A,一个小时不操作后再跳转应用B,此时会因为SSO的session已经过期导致无法同步登录状态,用户就得要重新登录,所以SSO的session过期时间应该根据需要合理设置,不应该设置太短。
最后留下一道思考题:如何同步退出登录状态?
当用户在应用A
退出登录时,只有应用A
和SSO
知道用户退出登录了,但其它应用却不得而知。
最简单的方式就是除SSO
之后,将其它应用的Session
过期时间配置尽可能短。又或者每次打开应用的首页都先跳转到SSO,如果已经登录,自然会重定向回来,这一个步骤对用户来说是透明的。
最后,由于每个应用都用了Shiro
实现接口权限校验,也用了Shiro
的注解,所以权限校验的实现,我们在SDK
适配了Shiro
的注解,但完全弃用了Shiro
。
[Java艺术] 微信号:javaskill
一个只推送原创文章的技术公众号,分享Java后端相关技术。
实现SSO单点登录的思考相关推荐
- SSO单点登录重定向解决方案
关注 "Java艺术" 我们一起成长! 继上篇<实现SSO单点登录的思考> 当我们写好SSO单点登录服务的代码后,通过调用接口方式验证,流程看似正常,但开始与前端联调就 ...
- Spring Cloud云架构 - SSO单点登录之OAuth2.0登录流程(2)
上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名+密码实现OAuth2.0的 ...
- [精华][推荐]CAS SSO单点登录服务端客户端学习
1.了解单点登录 SSO 主要特点是: SSO 应用之间使用 Web 协议(如 HTTPS) ,并且只有一个登录入口. SSO 的体系中有下面三种角色: 1) User(多个) 2) Web 应用(多 ...
- 学习CAS实现SSO单点登录
学习CAS实现SSO单点登录 网上找了几篇比较详细的教程,在这记录一下: 原理: CAS实现SSO单点登录原理 教程: 1.CAS实现单点登录(SSO)经典完整教程 2.SSO之CAS单点登录实例演示 ...
- 著名ERP厂商的SSO单点登录解决方案介绍一
著名ERP厂商的SSO单点登录解决方案介绍一 参考文章: (1)著名ERP厂商的SSO单点登录解决方案介绍一 (2)https://www.cnblogs.com/wintersun/p/557148 ...
- JAVA springboot ssm b2b2c多用户商城系统源码-SSO单点登录之OAuth2.0登录流程(2)
上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名+密码实现OAuth2.0的 ...
- SSO单点登录三种情况的实现方式详解
SSO单点登录三种情况的实现方式详解 单点登录(SSO--Single Sign On)对于我们来说已经不陌生了.对于大型系统来说使用单点登录可以减少用户很多的麻烦.就拿百度来说吧,百度下面有很多的子 ...
- CAS SSO 单点登录 实例
1.因为是本地模拟sso环境,而sso的环境测试需要域名,所以需要虚拟几个域名出来,步骤如下: 2.进入目录C:\Windows\System32\drivers\etc 3.修改hosts文件 12 ...
- cas跨域单点登录原理_CAS实现SSO单点登录原理
1. CAS 简介 1.1. What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨 ...
最新文章
- 2022-2028年中国硅质原料行业全景调研及投资前景展望报告
- 孩子数学成绩不好怎么办_孩子数学成绩不好,家长可以这样做
- 《高性能javascript》 领悟随笔之-------DOM编程篇(二)
- 关于最近练习PYTHON代码的一点心得
- 数据结构与算法笔记(十二)—— 查找算法(顺序查找、二分法查找)
- 用了30天整理的一些GO语言学习资料,2019请你加油
- dp括号匹配 网易面试题_面试题:大括号验证
- Nginx设置禁止通过IP访问服务器
- 炒菜机器人放食材的顺序_2年要开1000家 碧桂园旗下千玺机器人餐厅开业
- python绘制玫瑰花代码视频_python turtle玫瑰花绘制效果和源代码
- mac 更换默认蓝牙适配器_解决Switch最大遗憾,谷粒ROUTE Air蓝牙适配器:简单好用...
- 关于aab转apk的方法--bundletool
- 扫雷网站推荐及游戏攻略
- 推荐61个免费最好软件
- 通过hutool工具包实现将数据库中的全量数据导出,一张表一个sheet页,包含目录页,目录页和sheet页之间可以互相跳转
- 以太坊开发------Mist使用:合约及部署合约
- Auto CAD:图纸材质图例(石材、瓷砖、细木工板、钢筋混凝土、 木材、夹板、黏土砖 镜面/玻璃、软质吸音层 、钢/金属、硬质吸音层、硬隔层、基层龙骨、陶质类、涂料粉刷层)的设置之详细攻略
- 异贝,通过移动互联网技术,为中小微实体企业联盟、线上链接、线上线下自定义营销方案推送。案例53
- “左手画圆,右手画方”
- 身份证号码组件:lt;idcardgt; —— 快应用组件库H-UI