spring-security 过滤器链初始化以及执行过程分析-Servelt

spring-security 架构-Servlet

  • 版本信息
  • Java Web Servlet
    • servlet 处理 http 请求过程- Tomcat 容器
  • Spring Security 过滤器链如何注册?
  • DelegatingFilterProxy、FilterChainProxy、SecurityFilterChain
    • 执行流程图

SpringBoot web 项目默认使用的是 servlet 处理请求的,本章介绍 spring-security 过滤器链初始化以及执行过程。

版本信息

内容 版本
JDK 17
spring-boot-starter-web 3.2.2
spring-boot-starter-security 3.2.2
spring-security 6.2.1

Java Web Servlet

servlet 处理 http 请求过程- Tomcat 容器

spring-security 过滤器链初始化以及执行过程分析-Servelt_第1张图片

  1. 根据 url 匹配 使用那个 servlet 处理请求,源码方法 org.apache.catalina.mapper.Mapper#internalMapWrapper,具体内容参考博客https://blog.csdn.net/m0_52440465/article/details/122766656。SpringBoot 项目如果未配置Servlet,一般会匹配到 DispatcherServlet (Spring MVC)

  2. 创建过滤器链,方法org.apache.catalina.core.StandardWrapperValve#invoke
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第2张图片
    根据请求url 匹配需要执行的过滤器
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第3张图片

spring-security 过滤器链初始化以及执行过程分析-Servelt_第4张图片
3. 执行过滤器方法,在执行Spring Security 过滤器的时候,第一次请求会在Spring 容器中查找对应的过滤器链,注册到 Tomcat 容器中的是 Spring Security 的代理过滤器 DelegatingFilterProxy
4. servlet 处理请求,servlet 处理请求的时候经过若干个拦截器

Spring Security 过滤器链如何注册?

  1. DelegatingFilterProxyRegistrationBean 设置目标 Bean 的名字为 springSecurityFilterChain,在执行过滤器链的时候,会根据这个名字在Spring容器中查找对用的Spring Security过滤器链
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第5张图片
    将 DelegatingFilterProxyRegistrationBean 加载到服务上下文
    org.springframework.boot.web.servlet.ServletContextInitializerBeans#addServletContextInitializerBean(java.lang.String, org.springframework.boot.web.servlet.ServletContextInitializer, org.springframework.beans.factory.ListableBeanFactory)
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第6张图片
    org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#selfInitialize
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第7张图片
    获取 DelegatingFilterProxy 实例,添加到应用上下文
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第8张图片
    org.springframework.boot.web.servlet.AbstractFilterRegistrationBean#addRegistration
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第9张图片
    创建 DelegatingFilterProxy 实例, 方法org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean#getFilter
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第10张图片
    注册到Tomcat 容器中
    org.apache.catalina.core.ApplicationFilterRegistration#addMappingForUrlPatterns
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第11张图片

  2. 生成默认的过滤器链,DefaultSecurityFilterChain,boot 自动装载构建
    org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration.SecurityFilterChainConfiguration#defaultSecurityFilterChainspring-security 过滤器链初始化以及执行过程分析-Servelt_第12张图片
    org.springframework.security.config.annotation.web.builders.HttpSecurity#performBuild 方法中生成的默认过滤器链 DefaultSecurityFilterChain
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第13张图片

  3. 创建过滤器链代理类FilterChainProxy,Bean 的名字为 springSecurityFilterChain, 注意,这里生成Bean的名字和第一步 DelegatingFilterProxy 目标Bean 的名字是一致的
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第14张图片
    从这个Bean 的创建代码,可以看出,一个Bean可以支持多个SecurityFilterChain过滤器链的配置

  4. 构建过滤器链代理类 FilterChainProxywebSecurity.build() 方法会调用父类的 org.springframework.security.config.annotation.web.builders.WebSecurity#performBuild 方法,过滤器链代理类生成的代码片段如下
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第15张图片

DelegatingFilterProxy、FilterChainProxy、SecurityFilterChain

图片来源于官网 https://docs.spring.io/spring-security/reference/servlet/architecture.html#servlet-delegatingfilterproxy

DelegatingFilterProxy 委托代理过滤器类,服务启动初始化的时候会注册到Tomcat容器中。在http请求到达服务器,执行过滤器链方法的时候,根据目标Bean的名字 springSecurityFilterChain,在 Spring容器查找对应的Bean代理过滤器FilterChainProxy。代理过滤器会根据请求匹配到 SecurityFilterChain 过滤器链,然后执行对应的过滤器方法。

spring-security 过滤器链初始化以及执行过程分析-Servelt_第16张图片
spring-security 过滤器链初始化以及执行过程分析-Servelt_第17张图片
spring-security 过滤器链初始化以及执行过程分析-Servelt_第18张图片

spring-security 过滤器链初始化以及执行过程分析-Servelt_第19张图片

执行流程图

spring-security 过滤器链初始化以及执行过程分析-Servelt_第20张图片

  1. 创建过滤器链,调用的方法 org.apache.catalina.core.StandardWrapperValve#invoke, 执行创建过滤器链方法org.apache.catalina.core.ApplicationFilterFactory#createFilterChain
  2. DelegatingFilterProxy 执行doFilter逻辑,先判断是否初始化了目标过滤器,如果没有的,在Spring容器中,根据目标Bean的名字查找过滤器
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第21张图片
  3. FilterChainProxy 代理过滤器类,执行过滤器方法的时候,会根据请求匹配对应的Spring Security 过滤器链。org.springframework.security.web.FilterChainProxy#doFilterInternal
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第22张图片
    org.springframework.security.web.FilterChainProxy#getFilters(jakarta.servlet.http.HttpServletRequest) 匹配过滤器链,获取将要执行的过滤器列表
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第23张图片
  4. 执行过滤器方法,获取到过滤器列表之后,会构造一个虚拟过滤器链
    org.springframework.security.web.FilterChainProxy.VirtualFilterChainDecorator#decorate(jakarta.servlet.FilterChain, java.util.List)
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第24张图片
    执行过滤器逻辑 org.springframework.security.web.FilterChainProxy.VirtualFilterChain#doFilter
    spring-security 过滤器链初始化以及执行过程分析-Servelt_第25张图片

你可能感兴趣的:(Spring,Security,spring,spring,security)