Spring Security 过滤器链中的自定义过滤器
最后更新:2025年2月6日
1. 概述
在本快速教程中,我们将重点介绍 Spring Security 过滤器链的自定义过滤器编写。
更多阅读
Spring Security – @PreFilter 和 @PostFilter
通过实践示例学习如何使用 Spring Security @PreFilter 和 @PostFilter 注解。
了解更多 →
2. 创建过滤器
Spring Security 默认提供许多过滤器,而且大多数情况下这些过滤器就足够了。
当然,有时需要通过创建新的过滤器来在链中使用来实现新功能。
我们将从实现org.springframework.web.filter.GenericFilterBean开始。
GenericFilterBean是一个Spring-aware的简单javax.servlet.Filter实现。
我们只需要实现一个方法
public class CustomFilter extends GenericFilterBean {
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
}
3. 在安全配置中使用过滤器
我们可以自由选择 XML 配置或 Java 配置将过滤器连接到 Spring Security 配置。
3.1. Java 配置
我们可以通过创建一个SecurityFilterChain bean 以编程方式注册过滤器。
例如,它使用HttpSecurity实例上的addFilterAfter方法起作用
@Configuration
public class CustomWebSecurityConfigurerAdapter {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.addFilterAfter(
new CustomFilter(), BasicAuthenticationFilter.class);
return http.build();
}
}
有几种可能的方法
- addFilterBefore(filter, class) 在指定的过滤器class的位置之前添加一个过滤器。
- addFilterAfter(filter, class) 在指定的过滤器class的位置之后添加一个过滤器。
- addFilterAt(filter, class) 在指定的过滤器类位置添加一个过滤器。
- addFilter(filter) 添加一个过滤器,该过滤器必须是 Spring Security 提供的过滤器之一的实例或扩展。
3.2. XML 配置
我们可以使用custom-filter标签和这些名称之一将过滤器添加到链中,以指定我们过滤器的位置。
例如,可以通过after属性来指出
<http>
<custom-filter after="BASIC_AUTH_FILTER" ref="myFilter" />
</http>
<beans:bean id="myFilter" class="com.baeldung.security.filter.CustomFilter"/>
以下是所有用于精确指定在堆栈中放置我们的过滤器的属性
- after描述了自定义过滤器将放置在链中的紧挨着哪个过滤器之后。
- before定义了我们的过滤器应该放置在链中的哪个过滤器之前。
- position允许用自定义过滤器替换在显式位置的标准过滤器。
4. 仅在受保护的端点上应用 Spring Security 过滤器
现代应用程序通常提供公共端点和受保护的端点。全局应用自定义 Spring Security 过滤器会导致对公共端点进行不必要的处理。为了解决这个问题,我们可以通过使用 Spring Security 的SecurityFilterChain和RequestMatcher来专门针对受保护的端点应用过滤器。
@Bean
public SecurityFilterChain securedFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
authorizationManagerRequestMatcherRegistry.requestMatchers("/secured/**").authenticated())
.httpBasic(Customizer.withDefaults());
http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class);
return http.build();
}
此配置确保仅对匹配/secured/**的端点应用安全设置,如requestMatchers(“/secured/**”)所指定。
addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class)行确保自定义过滤器在BasicAuthenticationFilter之后应用,这意味着它仅在基本的身份验证过程之后执行。
这种方法允许对受保护的端点进行有针对性的安全处理,而不会影响公共端点。所有对/secured/**的请求都需要身份验证,由.authorizeHttpRequests()强制执行。
通过使用自定义SecurityFilterChain,我们可以隔离这些安全设置,保持应用程序的安全模块化和高效。 此设置可以防止公共端点的额外开销,并确保为受保护路径提供定制的身份验证处理,例如在身份验证入口点中的自定义失败响应。
5. 结论
在这篇快速的文章中,我们创建了一个自定义过滤器,并将其连接到 Spring Security 过滤器链。
支持本文的代码可在 GitHub 上获取。 一旦你以 Baeldung Pro 会员 身份登录,就开始学习并在项目上进行编码。















