1. 概述

Spring Security 的核心机制是基于一系列 Servlet 过滤器(Filter)构建的。每个过滤器都有其特定职责,而根据配置的不同,某些过滤器可能会被添加或移除。

在本文中,✅我们将介绍几种查找当前应用中注册的 Spring Security 过滤器的方法

2. 启用安全调试模式

最直观的方式是开启 Spring Security 的调试功能。该功能会在每次请求时输出详细的安全相关信息。

我们可以通过在 @EnableWebSecurity 注解中设置 debug = true 来启用调试:

@EnableWebSecurity(debug = true)

一旦启用后,发送请求到服务器时,控制台将打印出完整的安全过滤器链信息:

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  LogoutFilter
  UsernamePasswordAuthenticationFilter
  // ...
]

⚠️ 注意:虽然这种方式对调试很有帮助,但在生产环境中不建议开启,因为它会显著影响性能。

3. 日志方式查看过滤器

另一种方式是通过日志来查看 Spring Security 的过滤器调用过程。

我们可以在 application.properties 中增加如下配置来启用相关日志:

logging.level.org.springframework.security.web.FilterChainProxy=DEBUG

随后你会看到类似下面的日志输出:

DEBUG o.s.security.web.FilterChainProxy - /foos/1 at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
DEBUG o.s.security.web.FilterChainProxy - /foos/1 at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG o.s.security.web.FilterChainProxy - /foos/1 at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
DEBUG o.s.security.web.FilterChainProxy - /foos/1 at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG o.s.security.web.FilterChainProxy - /foos/1 at position 5 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
...

这些日志清晰地展示了每个请求经过的过滤器顺序和名称,非常适合排查问题。

4. 编程方式获取过滤器列表

如果你希望在代码中动态获取当前注册的所有安全过滤器,可以通过编程方式实现。

4.1 注入 springSecurityFilterChain Bean

首先,注入 Spring Security 自动创建的 springSecurityFilterChain Bean:

@Autowired
@Qualifier("springSecurityFilterChain")
private Filter springSecurityFilterChain;

⚠️ 注意:这里使用的是 Filter 类型而不是 FilterChainProxy,因为 WebSecurityConfiguration 中定义的 springSecurityFilterChain() 方法返回的就是 Filter 类型。

4.2 获取并遍历所有过滤器

接下来将其强转为 FilterChainProxy 并调用 getFilterChains() 方法获取过滤器链:

public void getFilters() {
    FilterChainProxy filterChainProxy = (FilterChainProxy) springSecurityFilterChain;
    List<SecurityFilterChain> list = filterChainProxy.getFilterChains();
    list.stream()
      .flatMap(chain -> chain.getFilters().stream()) 
      .forEach(filter -> System.out.println(filter.getClass()));
}

输出示例:

class org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter
class org.springframework.security.web.context.SecurityContextPersistenceFilter
class org.springframework.security.web.header.HeaderWriterFilter
class org.springframework.security.web.authentication.logout.LogoutFilter
class org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
...

💡 自 Spring Security 3.1 起,FilterChainProxy 是通过一组 SecurityFilterChain 来进行配置的。不过大多数项目通常只需要一个默认的 SecurityFilterChain

5. 常见重要安全过滤器简介

以下是一些常见的 Spring Security 核心过滤器及其作用:

  • UsernamePasswordAuthenticationFilter
    处理表单登录认证,默认拦截 /login 请求。

  • AnonymousAuthenticationFilter
    如果 SecurityContextHolder 中没有认证对象,则自动创建一个匿名用户对象放入上下文。

  • FilterSecurityInterceptor
    执行访问控制决策,如果权限不足则抛出异常。

  • ExceptionTranslationFilter
    捕获由 Spring Security 抛出的认证或授权异常,并做统一处理。

这些过滤器构成了 Spring Security 的核心执行流程,理解它们有助于我们更深入掌握整个框架的工作机制。

6. 小结

在这篇文章中,我们学习了三种查看 Spring Security 注册过滤器的方法:

方法 使用场景
安全调试模式 快速查看整体过滤器链结构,适合开发阶段
日志输出 查看请求经过的具体过滤器顺序,适合排查问题
编程方式 动态分析当前安全配置,适合高级定制需求

源码可从 GitHub 获取:https://github.com/eugenp/tutorials/tree/master/spring-security-modules/spring-security-web-boot-1


📌 友情提示: 生产环境慎用 debug 模式,避免敏感信息泄露和性能损耗。


原始标题:Find the Registered Spring Security Filters