0
点赞
收藏
分享

微信扫一扫

SpringSecurity OAuth实现单点登录源码解析-彻彻底底

玉新行者 2022-12-01 阅读 81


前言

这篇文章是建立在对SpringSecurity、SpringSecurity OAuth 、OAuth2.0协议、SSO单点登录流程有所了解的基础上,如果这部分不了解的话,源码分析起来就会比较处理,这个流程都稀里糊涂的,这篇文章会从一个未登录授权的请求,从SpringBoot集成的Tomcat一步一步到SpringSecurity再到SpringSecurity OAuth整个授权过程和单点登录的源码流程分析

环境准备

一个完整流程的SSO单点登录项目!​​完整项目地址​​

项目clone下来后项目结构如下

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_ide


这里建议不要直接使用IDEA打开security文件,推荐将sso-demo打成本地依赖,然后单独将sso-client1、sso-client2、sso-server使用IDEA打开,方便后面源码调试,因为在同一个IDEA中打开设置的断点,三个项目公用的依赖中的代码会重复的执行,跳来跳去,不便于我们调试!

源码分析

这里先发送一个请求,http://127.0.0.1:9992/client1/index.html,然后一路跟着下面断点走

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_02


注意:这是NetWork中什么都没有,这个没登录授权的请求,会被下面断点一个一个卡住!1.标记CoyoteAdapter-service

-----------------------------------------------------------------Tomcat接管请求---------------------------------------------------------------

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_03


这是整个请求到达Tomcat的入口,可以理解为请求的大门!

2.标记invoke()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_04


后续还有很多的invoke()方法需要标记,都是底层Tomcat的调用关系实现!

3.标记StandardEngineValve类中invoke()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_ide_05


4.标记ErrorReportValve类中invoke()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_06


5.标记StandardHostValve类中invoke()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_07

6.标记AuthenticatorBase类中invoke()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_08


7.标记StandardContextValve类中invoke()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_09


8.标记StandardWrapperValve类中invoke()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_10


SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_11


注意断点走到这里后得到filterChain为ApplicationFilterChain对象,然后调用ApplicationFilterChain类中的doFilter()方法

9.标记ApplicationFilterChain类中internalDoFilter()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_12


SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_13


doFilter()方法中的两个断点就可以不用打了,因为会循环调用internalDoFilter()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_14


最后选择org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean中的doFilter()方法,这里走到DelegatingFilterProxy类中SpringWeb开始开始接管代码流程

-----------------------------------------------------------SpringWeb接管请求----------------------------------------------------------------

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_15

10.标记DelegatingFilterProxy类中doFilter()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_16


这里会调用本类中的invokeDelegate()方法,顺带标记一下

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_17


得到此时delegate值为FilterChainProxy11.标记FilterChainProxy类中doFilter()方法

进入这里是SpringSecurity已经开始接管请求

---------------------------------------------------------SpringSecurity接管请求------------------------------------------------------------

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_18

此处调用本类中的doFilterInternal()方法,

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_ide_19


在doFilterInternal()方法中又会调用doFilter()方法,注意!!!此处的doFilter()方法不是刚开始的那个doFilter()方法而是下面的

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_20


这里又会进入循环

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_21


一直会等待值为FilterSecurityInterceptor,这是因为引入了SpringSecurity后才有的,那么这里就可以理解为请求开始正式进入SpringSecurity管控了,已经从Tomcat中脱离出来,开始走SpringSecurity的流程,在之前的文章中也有写过这个FilterSecurityInterceptor拦截器,这个拦截器我们可以理解为是SpringSecurity的大门!12.标记FilterSecurityInterceptor的doFilter()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_22


这里会调用本类的invoke()方法

标记invoke()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_23


进入beforeInvocation()方法13.标记AbstractSecurityInterceptor类中beforeInvocation()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_24


这行代码比较重要

this.accessDecisionManager.decide(authenticated, object, attributes);

在SpringSecurity起到一个决定作用,关系到请求的通过情况!
当然了这里刚开始发送的http://127.0.0.1:9992/client1/index.html这个请求是没有登录授权的,那么在行代码就会报错

14.标记AffirmativeBased类中decide()方法

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_25


这里就会抛出异常然后又会被AbstractSecurityInterceptor类中beforeInvocation()方法decide调用处捕获异常,代码如下

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_tomcat_26


然后这里的异常又会抛出

被ExceptionTranslationFilter接收这个类在写SpringSecurity有提到过,是一个SpringSecurity过滤器连上重要的一环

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_spring_27


中间蓝色的就是这个异常过滤器!最终会原路返回到CoyoteAdapter中

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_ide_28


这里会向浏览器中发送重定向login地址

SpringSecurity OAuth实现单点登录源码解析-彻彻底底_ide_29


举报

相关推荐

0 条评论