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 模式,避免敏感信息泄露和性能损耗。