前言

市场上一下主流的SSO技术搭配方案:

  1. SpringSecurity + OAuth2
  2. SpringSecurity + CAS 功能较弱,对前后端分离的项目支持不是很好
  3. Shiro + CAS
  4. JWT 可以自定义需求,灵活扩展鉴权方式

本篇主要是单点登录,不涉及鉴权,后面文章会再补充

xxl-sso 是一个国产 SSO 框架,基于 cookies 实现,也许你会考虑跨域问题,虽然 cookies 本身不跨域,但可以利用它实现跨域的 SSO。

1、拉取官方示例项目

gitee地址:https://gitee.com/xuxueli0323/xxl-sso
github地址:https://github.com/xuxueli/xxl-sso

模块说明:
  • xxl-sso-server:中央认证服务,支持集群
  • xxl-sso-core:Client端依赖
  • xxl-sso-samples:单点登陆Client端接入示例项目
    • xxl-sso-web-sample-springboot:基于Cookie接入方式,供用户浏览器访问,springboot版本
    • xxl-sso-token-sample-springboot:基于Token接入方式,常用于无法使用Cookie的场景使用,如APP、Cookie被禁用等,springboot版本
依赖环境:

JDK:1.7+
Redis:4.0+

修改本地host:
127.0.0.1 xxlssoserver.com127.0.0.1 xxlssoclient1.com127.0.0.1 xxlssoclient2.com
导入项目后启动:

修改 application.properties redis为本地地址后启动 xxl-sso-server:

### xxl-ssoxxl.sso.redis.address=redis://127.0.0.1:6378xxl.sso.redis.expire.minite=1440

完美报错,如果你跟我上图一样,那么说明你的 redis 设置了密码,这个官方示例代码是没有配置 redis 密码的,看控制台:

我们可以看到初始化时用到了 redis 的本地地址,那么只需要知道在哪用了这个地址,那么肯定就会有设置密码的地方。

果不其然,我们最终发现了,地址是通过 JedisShardInfo 这个对象传递进去的,进入这个对象后发现,竟然有个 password?这不就是我们要找的密码吗。

再次启动,成功启动。

同样的修改 xxl-sso-samples > xxl-sso-web-samples-sprigboot 的 properties 然后再启动。

2、认证流程

客户端端口号被我改成8085,认证中心保持默认端口号8080

届时,我们启动了两个项目,浏览器访问第一个域名:http://xxlssoclient1.com:8085/xxl-sso-web-sample-springboot

我们可以看到访问后将被重定向到认证中心 http://xxlssoserver.com:8080/xxl-sso-server ,后面携带参数 redirect_url ,其为界面跳转前的链接,认证通过后将再次重定向回原来的访问链接。

上图为认证成功后的图片,会携带 xxl_sso_sessionid,其用于识别用户登陆信息,并会保存至本地两份 cookie,皆用来保存 xxl_sso_sessionid ,一份当前域名(xxlssoclient1.com),一份认证中心(xxlssoserver.com)。

保存的两份 xxl_sso_sessionid 值是一样的。

xxl_sso_sessionid由来

在上图中的认证界面,点击登录后会调用 WebController > doLogin 方法,用户登录成功后会生成该用户的 xxl_sso_sessionid 信息,并保存至 redis 中,同时会把 xxl_sso_sessionid 写入客户端 cookie,然后将重定向到 redirect_url,并拼接 xxl_sso_sessionid 参数,如下图所示。

我们再来访问第二个客户端试试,http://xxlssoclient2.com:8085/xxl-sso-web-sample-springboot,就目前并未向 http://xxlssoclient2.com:8085 写入任何有关 cookie 用户会话信息:

神奇的一幕发生了,显然2号客户端也成功登陆了,并携带了跟客户端1一样的 xxl_sso_sessionid 信息,我们再来看一下 cookie 信息:

xxlssoclient2.com中的xxl_sso_sessionid哪里来的?

其实通过 debug 发现,在 xxlssoclient1.com 登陆的前提下,再去访问 xxlssoclient2.com 时,由于没有任何登陆信息同样也是首先会跳转至认证中心:

还记得客户端1登陆后在认证中心 xxlssoserver.com 同样留下 xxl_sso_sessionid 信息吗?

显然,客户端2号再跳转过来时复用了认证中心的 xxl_sso_sessionid,然后发现存在 xxl_sso_sessionid,且 xxl_sso_sessionid 在 redis 里也没过期,则认为用户已经登陆了,重新重定向到 xxlssoclient2.com

退出操作

看完了统一登录,再来看一下退出操作。

退出相对就比较简单了,主要就是验证 redis 中的 xxl_sso_sessionid,我们来看一下退出方法:

首先调用退出方法后会清空当前网站的 cookie、redis 中的 xxl_sso_sessionid,比如在 xxlssoclient1.com、xxlssoclient2.com 都登陆的情况下,通过 xxlssoclient2.com 退出当前用户,则首先会清空 xxlssoclient2.com 站点下的 cookie ,同时后台也会清空当前用户的 redis,那么再通过 xxlssoclient1.com 访问时,尽管携带 xxl_sso_sessionid,但此时该信息已经过期,所以会再次重定向认证中心。

xxl-sso小结

如上为 xxl-sso 架构图,其核心为:

sso-server:中央认证服务
sso-client:接入 sso 认证中心的客户端应用
sso-sessionId:登陆用户会话ID,SSO 登陆成功后为用户自动分配
sso-user:登陆用户信息,与 SSO sessionId 相对应

登陆流程剖析:
  1. 客户端访问受限资源时,将会自动重定向到 SSO Server 进入统一登录界面
  2. 用户登录成功之后将会为用户分配 SSO SessionId 并重定向返回来源客户端端应用,同时附带分配的 SSO SessionId
  3. 在客户端的 SSO 过滤器里验证 SSO SessionId 无误,将 SSO SessionId 写入到用户浏览器客户端域名下 cookie 中
  4. SSO 过滤器验证 SSO SessionId 通过,受限资源请求放行
注销流程剖析:
  1. 用户在客户端应用请求注销时,将会重定向到 SSO Server 自动销毁全局 SSO SessionId,实现全局销毁用户登陆信息;
  2. 然后,访问接入SSO 保护的任意客户端应用时,SSO 过滤器均会拦截请求并重定向到 SSO Server 的统一登录界面;

至此,通过 cookie+redis 解决了多端统一认证,全局 sessionId 解决了 session 共享的问题。

基于Cookie,相关概念
  • 登陆凭证存储:登陆成功后,用户登陆凭证被自动存储在浏览器Cookie中
  • 客户端校验登陆状态:通过校验请求Cookie中的是否包含用户登录凭证判断
  • 系统角色模型:
    -- SSO Server:认证中心,提供用户登陆、注销以及登陆状态校验等功能
    -- 客户端应用:受SSO保护的客户端Web应用,为用户浏览器访问提供服务
    -- 用户:发起请求的用户,使用浏览器访问

如果 Cookie 被禁用怎么办?

xxl-sso 同样提供了 基于 token 接入方式,用于无法使用Cookie的场景使用,如APP、Cookie被禁用等,详细可参考 xxl-sso-token-sample-springboot 项目。

基于Token,相关概念
  • 登陆凭证存储:登陆成功后,获取到登录凭证(xxl_sso_sessionid=xxx),需要主动存储,如存储在 localStorage、Sqlite 中
  • 客户端校验登陆状态:通过校验请求 Header参数 中的是否包含用户登录凭证(xxl_sso_sessionid=xxx)判断;因此,发送请求时需要在 Header 参数 中设置登陆凭证
  • 系统角色模型:
    -- SSO Server:认证中心,提供用户登陆、注销以及登陆状态校验等功能
    --客户端应用:受SSO保护的客户端Web应用,为用户请求提供接口服务
    -- 用户:发起请求的用户,如使用Android、IOS、桌面客户端等请求访问

更多信息请访问官方文档:http://www.xuxueli.com/xxl-sso/#/

后面会写一篇实际项目中接入 xxl-sso 框架的实例。

我创建了一个java相关的公众号,用来记录自己的学习之路,感兴趣的小伙伴可以关注一下微信公众号哈:niceyoo

借助xxl-sso实现SSO相关推荐

  1. 不要用JWT替代session管理(上):全面了解Token,JWT,OAuth,SAML,SSO

    通常为了弄清楚一个概念,我们需要掌握十个概念.在判断 JWT (Json Web Token) 是否能代替 session 管理之前,我们要了解什么是 token,以及 access token 和 ...

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

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

  3. 漫谈单点登录(SSO)(淘宝天猫)(转载)

    1. 摘要 ( 注意:请仔细看下摘要,留心此文是否是您的菜,若浪费宝贵时间,深感歉意!!!) SSO这一概念由来已久,网络上对应不同场景的成熟SSO解决方案比比皆是,从简单到复杂,各式各样应有尽有!开 ...

  4. 浅谈SAML, OAuth, OpenID和SSO, JWT和Session

    前言 通常为了弄清楚一个概念,我们需要掌握十个概念.在判断 JWT(JsonWebToken) 是否能代替 session 管理之前,我们要了解什么是 token,以及 access token 和 ...

  5. 深入浅出单点登录(SSO)

    1. 摘要 ( 注意:请仔细看下摘要,留心此文是否是您的菜,若浪费宝贵时间,深感歉意!!!) SSO这一概念由来已久,也是相当普遍的一种身份验证设计,网络上对应不同场景的SSO解决方案比比皆是,从简单 ...

  6. OAuth2.0(及OIDC 1.0)选型建议及SSO、SLO方案

    目录 1. 关于认证 2. OAuth 2.0 3. OIDC 1.0 4. OIDC选型建议 4.1 PKCE 5. SSO方案 5.1 SSO SPA 5.2 SSO WEB 6. SLO方案 6 ...

  7. 【架构设计】单点登录SSO设计与实现

    1.什么是SSO? SSO( Single Sign-On ),中文意即单点登录,单点登录是一种控制多个相关但彼此独立的系统的访问权限,拥有这一权限的用户可以使用单一的ID和密码访问某个或多个系统从而 ...

  8. JForum 的 SSO集成

    本文介绍 JForum与已有的web应用的整合,以及JForum单点登陆原理与配置. JForum可以单独作为一个BBS论坛运行,但是很多情况,我们需要在我们已有的WEB应用中集成JForum. JF ...

  9. 细说SSO单点登录(转)

    OAuth2.0: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-security.html ...

  10. 什么是单点登录(SSO)

    来源:Java3y(ID:java3y) 一.什么是单点登录? 单点登录的英文名叫做:Single Sign On(简称SSO). 在初学/以前的时候,一般我们就单系统,所有的功能都在同一个系统上. ...

最新文章

  1. dsp-asic-fpga
  2. 如果当初学习编程时能有人给我这些忠告该多好
  3. GARFIELD@02-25-2005
  4. 扒一扒MathType不为人知的技巧
  5. 英伟达发布全球唯一千万亿级集成型 AI 工作组服务器
  6. linux下实现getch()函数的功能
  7. Ubuntu18.10的chrome免输入密码
  8. mysql 默认事务隔离级别_MySQL 事务隔离级别详解
  9. java怎么根据编号修改数据类型_Java中怎么根据不同的输入数据类型调用不同的方法呢?...
  10. JS Navigator onLine 获取系统是否处于脱机模式
  11. 【安全思维导图】————4、Git思维导图
  12. CUDA 优化之 PReLU 性能调优
  13. axios配置多个请求地址(打包后可通过配置文件修改)
  14. 利用Python库中的imageio生成GIF格式的动图
  15. AWB调试中(Tuning)的几个问题
  16. MySQL 3306端口开启
  17. HyperLynx(二十四)电源完整性之直流压降分析(一)
  18. C# 获取汉字的拼音首字母和全拼(含源码)
  19. 视频教程-Python零基础入门教程-Python
  20. 投资即修行,千里之行始于足下

热门文章

  1. [vue] 怎么缓存当前打开的路由组件,缓存后想更新当前组件怎么办呢?
  2. 前端学习(2681):重读vue电商网站1之后台启动
  3. 前端学习(2655):vue2中用ref实现计算器
  4. 工作148:父子组件传值 获取时间戳
  5. 工作34:第三方登录
  6. 前端学习(1948)vue之电商管理系统电商系统之排序
  7. 前端学习(1613):oracle基本概念
  8. 前端学习(1287):node.js的组成
  9. 前端学习(811):api和webapi
  10. spring学习(41):属性注入