Spring Security 基于一系列 servlet 过滤器。每个过滤器都有特定的职责,根据配置,添加或删除过滤器。
在本教程中,我们将讨论查找已注册的 Spring Security Filters 的不同方法。
首先,我们将启用安全调试,它将记录每个请求的详细安全信息。
我们可以使用调试属性启用安全调试:
@EnableWebSecurity(debug = true)
这样,当我们向服务器发送请求时,所有的请求信息都会被记录下来。
我们还可以看到整个安全过滤器链:
- Security filter chain: [
- WebAsyncManagerIntegrationFilter
- SecurityContextPersistenceFilter
- HeaderWriterFilter
- LogoutFilter
- UsernamePasswordAuthenticationFilter
- // ...
- ]
接下来,我们将通过启用 FilterChainProxy的日志记录来找到我们的安全过滤器。
我们可以通过将以下行添加到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'
- ...
现在,我们将了解如何以编程方式获取已注册的安全过滤器。
我们将使用 FilterChainProxy来获取安全过滤器。
首先,让我们自动装配springSecurityFilterChain bean:
- @Autowired
- @Qualifier("springSecurityFilterChain")
- private Filter springSecurityFilterChain;
在这里,我们使用了 名称为springSecurityFilterChain的@Qualifier,类型为Filter,而不是 FilterChainProxy。 这是因为 WebSecurityConfiguration 中的 springSecurityFilterChain() 方法创建了Spring Security 过滤器链,返回类型为Filter 而不是 FilterChainProxy。
接下来,我们将此对象强制转换为FilterChainProxy并调用getFilterChains()方法:
- public void getFilters() {
- FilterChainProxy filterChainProxy = (FilterChainProxy) springSecurityFilterChain;
- List
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。
最后,让我们看一下一些重要的安全过滤器:
在这篇快速文章中,我们探讨了如何以编程方式和使用日志来查找已注册的 Spring Security 过滤器。
与往常一样,可以在 GitHub 上找到源代码。