xtyuns / DevTech

技术笔记, 见 Issues
0 stars 0 forks source link

SpringSecurity 源码笔记 #6

Open xtyuns opened 11 months ago

xtyuns commented 11 months ago

SpringSecurity 的功能是通过 DelegatingFilterProxyRegistrationBean 来向 Servlet 的 FilterChain 中添加了一个类型为 DelegatingFilterProxy 的 Filter 来实现的,DelegatingFilterProxy 会加载来自 BeanFactory 中类型为 FilterChainProxy 的 springSecurityFilterChain 来真正的实现 Servlet 过滤器的功能,springSecurityFilterChain 是整个 SpringSecurity 的核心,它作为 Servlet 容器中的一个 Filter 内部又使用一系列 SpringSecurity 相关的 Filter 组成了一个 VirtualFilterChain 从而实现 SpringSecurity 的功能。

大致流程为: image

xtyuns commented 11 months ago

spring-boot-starter-security 在 servlet web 中的自动装配

在 spring-boot-autoconfigure 中导入了 security 相关的配置类,因此在使用 spring-boot-starter-security 导入相关依赖后 security 配置类的 @Conditional 将成立,此时 security 的自动装配就会生效。

装配 HttpSecurity

  1. SecurityAutoConfiguration
  2. Import SpringBootWebSecurityConfiguration
  3. @EnableWebSecurity
  4. Import HttpSecurityConfiguration
  5. @Bean HttpSecurity

装配 defaultSecurityFilterChain

  1. SecurityAutoConfiguration
  2. Import SpringBootWebSecurityConfiguration
  3. @Bean defaultSecurityFilterChain(HttpSecurity http)

装配 FilterChainProxy(springSecurityFilterChain)

  1. SecurityAutoConfiguration
  2. Import SpringBootWebSecurityConfiguration
  3. @EnableWebSecurity
  4. Import WebSecurityConfiguration
  5. @Bean springSecurityFilterChain()

装配 DelegatingFilterProxyRegistrationBean

  1. SecurityFilterAutoConfiguration
  2. @Bean DelegatingFilterProxyRegistrationBean

因为 DelegatingFilterProxyRegistrationBean 继承自 AbstractFilterRegistrationBean 从而实现了 ServletContextInitializer 接口,所以在 Servlet 容器启动的时候会调用onStartup(ServletContext servletContext) 方法来将 DelegatingFilterProxy 添加到 ServletContext 的过滤器链

xtyuns commented 11 months ago

defaultSecurityFilterChain 中的过滤器列表

SecurityFilterChain 中的 Filter 都是通过 HttpSecurity 来配置的

DisableEncodeUrlFilter: 禁用 HttpServletResponse.encodeURL 包含 SessionID 的功能 WebAsyncManagerIntegrationFilter SecurityContextPersistenceFilter HeaderWriterFilter: 在请求前后为响应添加 header CsrfFilter: 为当前请求生成 csrf token LogoutFilter: 处理登出请求 UsernamePasswordAuthenticationFilter: 表单登录认证过滤器 DefaultLoginPageGeneratingFilter: 渲染默认登录页面 DefaultLogoutPageGeneratingFilter: 渲染默认登出页面 BasicAuthenticationFilter: BASIC authorization 认证过滤器 RequestCacheAwareFilter SecurityContextHolderAwareRequestFilter AnonymousAuthenticationFilter: 将未认证的请求设置一个匿名用户的认证信息放入 SecurityContextHolder 的认证过滤器 SessionManagementFilter ExceptionTranslationFilter FilterSecurityInterceptor: 鉴权过滤器

UsernamePasswordAuthenticationFilter

ProviderManager -> AuthenticationProvider -> parentProviderManager -> ...

  1. AnonymousAuthenticationProvider
  2. DaoAuthenticationProvider: AbstractUserDetailsAuthenticationProvider
xtyuns commented 10 months ago

SpringSecurity 工作流程: FilterChainProxy -> AuthorizeHttpRequestsConfigurer -> SecurityFilterChain -> $SecurityFilter -> AuthenticationManager -> AuthenticationProvider -> AbstractAuthenticationToken