zoukankan      html  css  js  c++  java
  • 借助xxl-sso实现SSO

    前言

    市场上一下主流的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.com
    127.0.0.1 xxlssoclient1.com
    127.0.0.1 xxlssoclient2.com
    导入项目后启动:

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

    ### xxl-sso
    xxl.sso.redis.address=redis://127.0.0.1:6378
    xxl.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

  • 相关阅读:
    TCP源码—连接建立
    TCP系列02—连接管理—1、三次握手与四次挥手
    TCP系列01—概述及协议头格式
    ubuntu软件管理apt与dpkg
    318. Maximum Product of Word Lengths
    317. Shortest Distance from All Buildings
    316. Remove Duplicate Letters
    315. Count of Smaller Numbers After Self
    314. Binary Tree Vertical Order Traversal
    313. Super Ugly Number
  • 原文地址:https://www.cnblogs.com/niceyoo/p/11312101.html
Copyright © 2011-2022 走看看