spring-security过滤器
- 版本信息
- 过滤器配置
- 过滤器配置相关类图
- 过滤器加载过程
- 创建 HttpSecurity Bean 对象
- 创建过滤器
- 过滤器作用
- ExceptionTranslationFilter
- 自定义过滤器
本章介绍 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 对象
- SpringBoot 自动装载类
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration

@Import导入org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration

- Spring Security 核心注解类
@EnableWebSecurity

@Import导入org.springframework.security.config.annotation.web.configuration.HttpSecurityConfiguration

- 在
HttpSecurityConfiguration配置类中开始创建HttpSecurity的bean 对象

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

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

从这段代码可以看出,可以自定义过滤器的配置类,对扩展开放√
创建过滤器
- Spring Boot 自动装载在之前已分析,直接定位到
org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration, 在这个类中有创建过滤器链的Bean

- 默认过滤器链编译过程,查看
http.build()方法

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

在编译的过程中,会读取之前的配置类,将相关的过滤器添加到过滤器链,查看configure()方法

- 在配置类中,创建过滤器类,将过滤器类加载到过滤器链,列举一个配置类
org.springframework.security.config.annotation.web.configurers.CsrfConfigurer#configure,其它的配置类和这个相似

将过滤器添加到列表org.springframework.security.config.annotation.web.builders.HttpSecurity#filters

- 构建过滤器链,
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.access.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.AccessDeniedException;
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 hasAccess = isUserAllowed(tenantId);
if (hasAccess) {
filterChain.doFilter(request, response);
return;
}
throw new AccessDeniedException("Access denied");
}
private boolean isUserAllowed(String tenantId) {
// TODO check
return false;
}
}
避免过滤器注册到 Tomcat 中,可以参考如下代码








![[office] excel图表怎么发挥IF函数的威力 #微信#媒体](https://img-blog.csdnimg.cn/img_convert/fdcb58c6faa0c151dc377882a37eb25f.png)











