xxl-sso源码解读

文章目录

  • xxl-sso源码解读
  • 前言
  • 一、XXL-SSO是什么?
  • 二、搭建步骤
  • 三、系统简述
    • 1、xxl-sso-server
    • 2、xxl-sso-core
    • 3、 xxl-sso-web-sample-springboot和xxl-sso-token-sample-springboot
  • 四、基于Cookie方式
    • 1、项目运行
    • 2、首次登录
    • 3、跨域系统首次登录
    • 4、再次访问
    • 5、登出操作

前言

登录一直是所有系统的必不可少的一部分,也是极其重要的一个功能。随着技术思想的演变,通过解读许雪里大神的xxl-sso来了解处理跨域系统登录问题的方式和思路会对自己有个比较大的提升。当然下面的分析都是靠个人理解,如果有不对的地方希望可以在评论区指正。下面图片中代码看不清的话,点击一下放大就可以了。

一、XXL-SSO是什么?

XXL-SSO 是一个分布式单点登录框架。只需要登录一次就可以访问所有相互信任的应用系统。拥有”轻量级、分布式、跨域、Cookie+Token均支持、Web+APP均支持”等特性。

二、搭建步骤

具体搭建步骤请查看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版本

1、xxl-sso-server

这个项目是整个sso的认证中心,未登录状态下访问其他系统就会重定向到该系统的登录页面,并进行认证授权。

XxlSsoConfig:项目启动时读取配置文件中的redis地址和redis过期时间来初始化redis
用户权限拦截器是让开发者自由去根据具体业务进行用户权限拦截验证
其他的文件都是可以结合实际情况定制开发

2、xxl-sso-core

这个项目是sso的核心,实际使用中其他系统需要引入这个项目的maven依赖。


Conf:存储自定义的一些常量值,为了避免魔法值
过滤器和处理类是重点,之后的源码解读会重点讲解

3、 xxl-sso-web-sample-springboot和xxl-sso-token-sample-springboot

这两个项目是简单搭建的使用案例,分别的基于cookie和token的接入方式。

四、基于Cookie方式

1、项目运行

首先启动xxl-sso-server中央认证服务

xxl-sso-server项目启动后,在初始化Bean时,XxlSsoConfig配置类由于实现了InitializingBean接口,会执行afterPropertiesSet(),将配置文件中的redis地址传入redis工具类中并初始化;设置sso登录操作类redis信息过期时间。

然后启动xxl-sso-web-sample-springboot项目,项目启动时XxlSsoConfig从配置文件中读取配置参数初始化redis和XxlSsoWebFilter过滤器。

XxlSsoWebFilter初始化时会将中央认证服务(xxl-sso-server)地址,登出地址和不需要过滤的地址初始化,初始化完成后会打印在控制台。在每次符合拦截条件的地址便会被拦截器拦截执行doFilter(),因为过滤器是单例的,所以项目启动时加载初始化后,上述三个参数在方法中一直可以使用。

2、首次登录

首次登录原理时序图

项目都启动完后,在浏览器中输入http://xxlssoclient1.com:8081/xxl-sso-web-sample-springboot/,模拟首次访问客户端应用,
首先会被xxl-sso-core中的XxlSsoWebFilter给拦截执行doFilter()方法,如下图所示,首先会从request中拿到请求路径,然后判断是否在白名单路径中,如果在的话则不再执行下面的操作,直接放行。

再往下走,如下图所示,判断本次请求是否是登出,登出操作后面再讲。

继续往下走,如下图所示,执行XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(req, res);,执行这个方法是去获取登录对象,结果为null,执行第二个红框的代码,由于本次是get请求,没有request请求头中没有content-type,所以isJson=false,继续执行第三个红框中的代码,很明显是拼接url(http://xxlssoserver.com:8080/xxl-sso-server/login?redirect_url=http://xxlssoclient1.com:8081/xxl-sso-web-sample-springboot/),该url由认证中心的地址?redirect_url=本次请求的地址,然后重定向到该地址

最后浏览器页面就变成下图所示,跳转到了认证中心提供的统一的登录页面

在输入用户名和密码后,点击登录,由于认证中心xxl-sso-server也集成了xxl-sso-core,但是没有配置xxl-sso-core中的XxlSsoWebFilter拦截器,所以不会被拦截,所以post请求登录后,直接访问到了xxl-sso-server后台/doLogin方法,代码如下图,首先是判断是否记住密码,然后根据用户名密码校验用户信息是否正确(此处可以根据业务对接数据库进行信息校验),信息校验成功将用户信息赋予XxlSsoUser对象,然后执行makeSessionId()根据XxlSsoUser生成sessionId,makeSessionId方法中根据用户的id拼接version来组成sessionId(version可以自行定义生成规则,但是不能重复),然后进行用户信息存储,执行SsoWebLoginHelper.login(),在此方法中首先根据生成的sessionid拿到用户id作为key执行SsoLoginStore.put(storeKey, xxlUser)将用户信息存入redis中,并设置过期时间,随后执行CookieUtil.set(response, Conf.SSO_SESSIONID, sessionId, ifRemember),将sessionid存入cookie中,方法比较简单就不赘述了,值得注意的是,如果是记住密码的话,因为cookie没法设置永不过期,就把cookie过期时间设置为Integer.MAX_VALUE,一个32位二进制最大的数。登录完成后,便将要访问的路径拼接sessionid然后重定向,路径为http://xxlssoclient1.com:8081/xxl-sso-web-sample-springboot/?xxl_sso_sessionid=1000_ea9a88a094b04b989deab53fcfd8d3f0。

此时http://xxlssoclient1.com:8081/xxl-sso-web-sample-springboot/?xxl_sso_sessionid=1000_ea9a88a094b04b989deab53fcfd8d3f0该路径是访问的应用系统xxl-sso-web-sample-springboot,所以被拦截进行处理,每次都是先判断是否在白名单和是否是登出操作,这个上面说过了就不赘述了,再往下是执行SsoWebLoginHelper.loginCheck(req, res),可以看到是从cookie中取不到sessionid,就从请求URL中拿到了xxl_sso_sessionid(就是sessionId,只是名字不同),然后执行SsoTokenLoginHelper.loginCheck(cookieSessionId),在此方法中根据sessionid拿到userid,再根据userid当做key去redis中取XxlSsoUser,将sessionid中的version和XxlSsoUser的version进行对比,这个加入verison对比的过程是乐观锁的实现,对比没有问题后,判断登录的时间有没有超过设定过期时间的一半,超过一半的话就重新赋予一个新的时间,返回XxlSsoUser给SsoWebLoginHelper.loginCheck(req, res),继续往下执行,此时执行 request.setAttribute(Conf.SSO_USER, xxlUser),将用户信息放到request域中,过滤器通过。

过滤器通过后,便进入IndexController,跳转到index页面了,到这里单点登录的流程就完成了。

3、跨域系统首次登录

时序图

根据上面的登录原理我们知道了,一个网站登陆之后会在cookie中添加一个sessionId,下次再访问该网站时,会拿到这个sessionId,然后判断登录信息是否有效。那如果是跨域呢,我们知道跨域时cookie是不共享的,难道访问http://xxlssoclient1.com:8081/xxl-sso-web-sample-springboot/登录后,再访问跨域的类似的系统如http://xxlssoclient1.com:8082/xxl-sso-web-sample-springboot/还需要登陆吗?根据我们的经验和使用习惯,肯定是不需要再登录的,这也是跨域sso要解决的问题。
我们copy一份xxl-sso-web-sample-springboot代码,创建xxl-sso-web-sample-springboot-twox项目,
启动项目,这样我们就有两个客户端了

  • http://xxlssoclient1.com:8081/xxl-sso-web-sample-springboot/
  • http://xxlssoclient2.com:8082/xxl-sso-web-sample-springboot/
    首先访问http://xxlssoclient1.com:8081/xxl-sso-web-sample-springboot/,首次登录后,然后在浏览器新开一个标签页输入http://xxlssoclient2.com:8082/xxl-sso-web-sample-springboot/,回车访问

首先还是会被XxlSsoWebFilter拦截器拦截,进行白名单和登出判断,然后在SsoWebLoginHelper.loginCheck(req, res)方法里从cookie和url请求参数中都拿不到sessionId,所以XxlSsoUser为null,根据if判断重定向到http://xxlssoserver.com:8080/xxl-sso-server/login?redirect_url=http://xxlssoclient2.com:8082/xxl-sso-web-sample-springboot/,

请求在xxl-sso-server的login方法,如下图,又一次执行了SsoWebLoginHelper.loginCheck(request, response),注意这次是从xxl-sso-server中央认证中心的cookie域中拿的sessionId,由于第一次登陆时该cookie已经有了sessionId,所以可以取到sessionId,利用xxl-sso-server的cookie来十分巧妙的解决了所有跨域或者不跨域系统的登录所遇到的cookie共享问题。拿到XxlSsoUser对象后,重定向到http://xxlssoclient2.com:8082/xxl-sso-web-sample-springboot/?xxl_sso_sessionid=1000_6451438d7ee3483c8b345e6b9e02d8f0,接下来的操作和首次登陆中最后几步操作一样,就不再赘述了。

4、再次访问

当再次访问已经登录过的系统时,由于之前的登录已经在cookie中设置了sessionId,所以只需要从cookie中取sessionId然后验证即可,原理比较简单。

5、登出操作

时序图

客户端登出时,会被拦截器拦截,如下图所示,判断是登出请求,删除该系统cookie中的sessionId信息,然后跳转到http://xxlssoserver.com:8080/xxl-sso-server/logout,重定向到xxl-sso-server去注销。

在xxl-sso-server中的logout方法中,首先执行 SsoWebLoginHelper.logout(request, response),从xxl-sso-server的cookie中拿到sessionId,再根据sessionId拿到userid作为key去redis删除登录用户信息,然后从cookie中清除sessionId。最后重定向到登录页面。

其他已经登录的系统再请求操作时,由于redis中已经删除了登录用户信息,所以获取用户信息失败,然后重定向xxl-sso-server服务,获取xxl-sso-server域下cookie失败,从redis中查询用户信息失败,跳转登陆页。

xxl-sso源码解读(基于Cookie)相关推荐

  1. java oauth sso 源码_基于Spring Security Oauth2的SSO单点登录+JWT权限控制实践

    概 述 在前文<基于Spring Security和 JWT的权限系统设计>之中已经讨论过基于 Spring Security和 JWT的权限系统用法和实践,本文则进一步实践一下基于 Sp ...

  2. PCL:超详细的基于法向量和曲率的区域生长算法原理以及源码解读

    ---------原理介绍: (1)首先计算出来各点的曲率值,将曲率值按照从小到大的顺序进行排序. (2)设置一空的种子点序列和一个空的聚类数组. (3)选取曲率最小的点放入上述种子点序列中. (4) ...

  3. Pseudo-document-based Topic Model(基于伪文档的主题模型)的理解以及源码解读

    本文作者:合肥工业大学 管理学院 钱洋 email:1563178220@qq.com 内容可能有不到之处,欢迎交流. 未经本人允许禁止转载. 论文来源 Zuo Y, Wu J, Zhang H, e ...

  4. xxl-job源码解读:调度器schedule

    xxl-job源码解读:调度器schedule 本文基于xxl-job的2.3.1版本 基本说明 基本原理概述 调用器主要的用于判断定时任务的执行时间,按时调用触发器(trigger),再由触发器去获 ...

  5. tomcat源码解读(一)

    tomcat源码解读(一) 什么是 tomcat ? Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容器,按照Sun Microsystems提供的技术 规范, ...

  6. 【Android】OkHttp源码解读逐字稿(1)-拦截器

    目录 0.前言 1.OkHttp的简单使用 2.浅析开始 拦截器 链式调用流程示意图 第 0 个拦截器 第一个 拦截器 RetryAndFollowUpInterceptor 第二个拦截器 Bridg ...

  7. 【Android】OkHttp源码解读逐字稿(2)-OkHttpClient

    目录 0.前言 1.各个属性浅析 01.dispatcher 02.connectionPool 03.interceptors&networkInterceptors 04.eventLis ...

  8. Bert系列(二)——源码解读之模型主体

    本篇文章主要是解读模型主体代码modeling.py.在阅读这篇文章之前希望读者们对bert的相关理论有一定的了解,尤其是transformer的结构原理,网上的资料很多,本文内容对原理部分就不做过多 ...

  9. Alamofire源码解读系列(九)之响应封装(Response)

    本篇主要带来Alamofire中Response的解读 前言 在每篇文章的前言部分,我都会把我认为的本篇最重要的内容提前讲一下.我更想同大家分享这些顶级框架在设计和编码层次究竟有哪些过人的地方?当然, ...

最新文章

  1. 急招 Golang 熟手,来做 5G 事业。
  2. HDU 1297 Children’s Queue
  3. intellij idea 最常用的快捷键
  4. 华为服务器更改从系统盘启动不了,华为服务器设置启动项
  5. python/数据库操作补充—模板—Session
  6. Java 方法重载和覆盖重写的区别及注意事项
  7. 电脑端的全能扫描王:图片转文字识别、识别pdf、图片中的文字,图片提取txt...
  8. 在做UDP传输的时候,出现的这个问题,哪个大佬能帮忙看一看啊
  9. 判断一个正整数是否为2的整数次幂的宏定义
  10. 简单解决SVN cleanup failed to process the following paths错误
  11. 深恶痛绝!关闭win10自动更新的办法
  12. 个人网站---利用WordPress搭建个人网站
  13. jQuery插件,UI
  14. 数据库通过出生日期计算年龄
  15. JixiPix Rainy Daze for Mac(照片下雨特效工具)
  16. 《深入浅出DPDK》——DPDK网络功能虚拟化
  17. 【C语言】*p++与(*p)++的区别
  18. 更改sqlserver服务器的登录名称
  19. String s=new String(xback)和String s=xback的区别?
  20. 基于python-opencv实现鼠标绘制矩形、直线并根据直线斜率实现图片旋转

热门文章

  1. 试用码云gitee上开源项目“小威架构 / boot-backend“的代码生成器遇到的坑
  2. 使用Pandoc将Markdown文件转换为文字处理器文档
  3. ERR_PNPM_META_FETCH_FAIL GET https://registry.npmjs.org/@webpack-cli%2Fserve: request to https://re
  4. ExampleMatcher
  5. Flowable多实例会签功能来袭
  6. 时间不语,岁月要歌-我的2021
  7. 如何使用hadoop进行Bert tokenize
  8. css margin属性 auto,css中margin:auto属性的使用方法
  9. Linux nice及renice命令使用-验证篇
  10. 简单XMLSAX解析