spring-security 过滤器 (三)

spring-security 过滤器 (三)

本章介绍 spring-security 过滤器配置类 HttpSecurity,过滤器加载过程,自定义过滤器

版本信息

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

过滤器配置

过滤器配置相关类图

过滤器链由HttpSecurity的配置类配置生成的,在HttpSecurity.build()的时候添加至过滤器链,主要的配置类如下

org.springframework.security.config.annotation.web.configurers.CsrfConfigurer
org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer
org.springframework.security.config.annotation.web.configurers.HeadersConfigurer
org.springframework.security.config.annotation.web.configurers.SessionManagementConfigurer
org.springframework.security.config.annotation.web.configurers.SecurityContextConfigurer
org.springframework.security.config.annotation.web.configurers.RequestCacheConfigurer
org.springframework.security.config.annotation.web.configurers.AnonymousConfigurer
org.springframework.security.config.annotation.web.configurers.ServletApiConfigurer
org.springframework.security.config.annotation.web.configurers.LogoutConfigurer
org.springframework.security.config.annotation.web.configurers.CorsConfigurer

过滤器加载过程

创建 HttpSecurity Bean 对象

  1. SpringBoot 自动装载类 org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
  2. @Import 导入 org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration
  3. Spring Security 核心注解类 @EnableWebSecurity
  4. @Import 导入 org.springframework.security.config.annotation.web.configuration.HttpSecurityConfiguration
  5. HttpSecurityConfiguration 配置类中开始创建 HttpSecurity 的bean 对象

    可以在 org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder#add 方法中加个断点,看初始化添加了多少个配置类

    配置类还可以扩展的,基于SPI扩展 org.springframework.security.config.annotation.web.configuration.HttpSecurityConfiguration#applyDefaultConfigurers

    从这段代码可以看出,可以自定义过滤器的配置类,对扩展开放√

创建过滤器

  1. Spring Boot 自动装载在之前已分析,直接定位到 org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration, 在这个类中有创建过滤器链的Bean
  2. 默认过滤器链编译过程,查看 http.build() 方法

    首先判断是否已经构建了,防止重复构建。再执行 doBuild() 方法

    在编译的过程中,会读取之前的配置类,将相关的过滤器添加到过滤器链,查看 configure() 方法
  3. 在配置类中,创建过滤器类,将过滤器类加载到过滤器链,列举一个配置类org.springframework.security.config.annotation.web.configurers.CsrfConfigurer#configure,其它的配置类和这个相似

    将过滤器添加到列表 org.springframework.security.config.annotation.web.builders.HttpSecurity#filters
  4. 构建过滤器链,org.springframework.security.config.annotation.web.builders.HttpSecurity#performBuild

过滤器作用

ExceptionTranslationFilter

官网介绍 https://docs.spring.io/spring-security/reference/servlet/architecture.html#servlet-exceptiontranslationfilter



注意,执行顺序在 ExceptionTranslationFilter 之后的过滤器才会捕获到异常,并进行异常处理。默认过滤器的顺序如图所示,在 ExceptionTranslationFilter 之后的过滤器只有 org.springframework.security.web.a***ess.intercept.AuthorizationFilter,该过滤器抛出的异常可以被异常过滤器捕获到

自定义过滤器

参考官网 https://docs.spring.io/spring-security/reference/servlet/architecture.html#adding-custom-filter,提示部分的内容挺好的

根据提示可以定义过滤器代码如下

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.nio.file.A***essDeniedException;

public class TenantFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String tenantId = request.getHeader("X-Tenant-Id");
        boolean hasA***ess = isUserAllowed(tenantId);
        if (hasA***ess) {
            filterChain.doFilter(request, response);
            return;
        }
        throw new A***essDeniedException("A***ess denied");
    }

    private boolean isUserAllowed(String tenantId) {
        // TODO check
        return false;
    }
}

避免过滤器注册到 Tomcat 中,可以参考如下代码

配置自定义过滤器到过滤器链

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.addFilterBefore(new TenantFilter(), AuthorizationFilter.class);
        return http.build();
    }
}
转载请说明出处内容投诉
CSS教程_站长资源网 » spring-security 过滤器 (三)

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买