关注 “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获取到系统ASessionId,然后根据SessionIdRedis查询用户信息,再写入系统BSession中。如此就能实现自动携带SessionId跳转。

只不过,这种方式要求每个系统都实现一遍这样的功能,并且每个系统也都要提供登录功能。

为了简化实现,以及后续的新系统不再重复实现登录功能,我们应该考虑将登录功能抽离为一个独立的应用,其它系统不再提供登录功能。

将登录功能抽离为独立应用之后,实现SSO单点登录流程梳理如下:

SSO抽离为一个独立的应用,独立的域名,提供登录页面,要求其它应用不再提供登录页面,都必须通过SSO登录。

其它应用在接收到请求时,首先根据session判断是否已经登录了,如果未登录则重定向到SSO登录页面,并且在重定向链接带上是哪个应用跳转过来的,当用户在SSO登录成功后重定向回原来的应用。

浏览器重定向到SSO登录页面时,浏览器会存储SSOcookie,用户在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应用:

  1. 提供登录功能,支持从哪个应用重定向过来,登录成功后就重定向回哪个应用去;

  2. 提供根据token获取当前登录用户信息的接口。

其它应用:

  1. 未登录则重定向跳转到SSO,在跳转链接上带上登录成功后重定向调用的接口;

  2. 提供给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退出登录时,只有应用ASSO知道用户退出登录了,但其它应用却不得而知。

最简单的方式就是除SSO之后,将其它应用的Session过期时间配置尽可能短。又或者每次打开应用的首页都先跳转到SSO,如果已经登录,自然会重定向回来,这一个步骤对用户来说是透明的。

最后,由于每个应用都用了Shiro实现接口权限校验,也用了Shiro的注解,所以权限校验的实现,我们在SDK适配了Shiro的注解,但完全弃用了Shiro

[Java艺术] 微信号:javaskill

一个只推送原创文章的技术公众号,分享Java后端相关技术。

实现SSO单点登录的思考相关推荐

  1. SSO单点登录重定向解决方案

    关注 "Java艺术" 我们一起成长! 继上篇<实现SSO单点登录的思考> 当我们写好SSO单点登录服务的代码后,通过调用接口方式验证,流程看似正常,但开始与前端联调就 ...

  2. Spring Cloud云架构 - SSO单点登录之OAuth2.0登录流程(2)

    上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名+密码实现OAuth2.0的 ...

  3. [精华][推荐]CAS SSO单点登录服务端客户端学习

    1.了解单点登录 SSO 主要特点是: SSO 应用之间使用 Web 协议(如 HTTPS) ,并且只有一个登录入口. SSO 的体系中有下面三种角色: 1) User(多个) 2) Web 应用(多 ...

  4. 学习CAS实现SSO单点登录

    学习CAS实现SSO单点登录 网上找了几篇比较详细的教程,在这记录一下: 原理: CAS实现SSO单点登录原理 教程: 1.CAS实现单点登录(SSO)经典完整教程 2.SSO之CAS单点登录实例演示 ...

  5. 著名ERP厂商的SSO单点登录解决方案介绍一

    著名ERP厂商的SSO单点登录解决方案介绍一 参考文章: (1)著名ERP厂商的SSO单点登录解决方案介绍一 (2)https://www.cnblogs.com/wintersun/p/557148 ...

  6. JAVA springboot ssm b2b2c多用户商城系统源码-SSO单点登录之OAuth2.0登录流程(2)

    上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名+密码实现OAuth2.0的 ...

  7. SSO单点登录三种情况的实现方式详解

    SSO单点登录三种情况的实现方式详解 单点登录(SSO--Single Sign On)对于我们来说已经不陌生了.对于大型系统来说使用单点登录可以减少用户很多的麻烦.就拿百度来说吧,百度下面有很多的子 ...

  8. CAS SSO 单点登录 实例

    1.因为是本地模拟sso环境,而sso的环境测试需要域名,所以需要虚拟几个域名出来,步骤如下: 2.进入目录C:\Windows\System32\drivers\etc 3.修改hosts文件 12 ...

  9. cas跨域单点登录原理_CAS实现SSO单点登录原理

    1.      CAS 简介 1.1.  What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨 ...

最新文章

  1. 2022-2028年中国硅质原料行业全景调研及投资前景展望报告
  2. 孩子数学成绩不好怎么办_孩子数学成绩不好,家长可以这样做
  3. 《高性能javascript》 领悟随笔之-------DOM编程篇(二)
  4. 关于最近练习PYTHON代码的一点心得
  5. 数据结构与算法笔记(十二)—— 查找算法(顺序查找、二分法查找)
  6. 用了30天整理的一些GO语言学习资料,2019请你加油
  7. dp括号匹配 网易面试题_面试题:大括号验证
  8. Nginx设置禁止通过IP访问服务器
  9. 炒菜机器人放食材的顺序_2年要开1000家 碧桂园旗下千玺机器人餐厅开业
  10. python绘制玫瑰花代码视频_python turtle玫瑰花绘制效果和源代码
  11. mac 更换默认蓝牙适配器_解决Switch最大遗憾,谷粒ROUTE Air蓝牙适配器:简单好用...
  12. 关于aab转apk的方法--bundletool
  13. 扫雷网站推荐及游戏攻略
  14. 推荐61个免费最好软件
  15. 通过hutool工具包实现将数据库中的全量数据导出,一张表一个sheet页,包含目录页,目录页和sheet页之间可以互相跳转
  16. 以太坊开发------Mist使用:合约及部署合约
  17. Auto CAD:图纸材质图例(石材、瓷砖、细木工板、钢筋混凝土、 木材、夹板、黏土砖 镜面/玻璃、软质吸音层 、钢/金属、硬质吸音层、硬隔层、基层龙骨、陶质类、涂料粉刷层)的设置之详细攻略
  18. 异贝,通过移动互联网技术,为中小微实体企业联盟、线上链接、线上线下自定义营销方案推送。案例53
  19. “左手画圆,右手画方”
  20. 身份证号码组件:lt;idcardgt; —— 快应用组件库H-UI

热门文章

  1. jQuery 基础 筛选和遍历 jQuery 对象
  2. 10年老司机,未必知道的IT基础知识
  3. EOS的经济模型是什么?
  4. Linux 安装Oracle11g完整安装图文教程另附基本操作 (分享)
  5. 读取佳能单反相机快门次数的方法
  6. SVM支持向量机-拉格朗日乘子与对偶问题(1)
  7. Java 类加载顺序与成员变量初始化
  8. 202011 网络是通的,数据发不过去(接受不到)
  9. linux操作系统之常用远程管理命令:关机和重启命令shutdown详解 简单易懂~
  10. fast-reid中的sbs