简介
在 Spring Boot 3.x 中,根据不同的 URL 前缀添加不同的过滤器可以通过多种方式实现。本文介绍了三种方案,最终第三种方案被证明是有效的。
方案一:使用 securityMatcher
匹配
通过 securityMatcher
方法为不同的 URL 前缀添加过滤器:
java
http.securityMatcher("/api/**")
.addFilterBefore(authenticationFilter, UsernamePasswordAuthenticationFilter.class);
http.securityMatcher("/openapi/**")
.addFilterBefore(openApiAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
这种方法在某些情况下可能无法正确工作,因为多个 securityMatcher
可能会相互干扰。
方案二:定义不同的 SecurityFilterChain
通过定义多个 SecurityFilterChain
来为不同的 URL 前缀配置安全策略和过滤器:
java
@Bean
@Order(1)
public SecurityFilterChain apiSecurityFilterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable())
.securityMatcher("/api/**")
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/api/auth/**", "/api/user/create").permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(exception -> exception
.authenticationEntryPoint(authenticationEntryPoint)
)
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.addFilterBefore(authenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
@Order(2)
public SecurityFilterChain openApiSecurityFilterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable())
.securityMatcher("/openapi/**")
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/openapi/**").permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(exception -> exception
.authenticationEntryPoint(authenticationEntryPoint)
)
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.addFilterBefore(openApiAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
这种方法通过定义多个 SecurityFilterChain
来确保每个 URL 前缀有独立的安全配置,避免了冲突。
方案三:重写 shouldNotFilter
方法
通过在过滤器中重写 shouldNotFilter
方法来控制过滤器的应用范围:
java
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
String path = request.getRequestURI();
return path.startsWith("/openapi/");
}
这种方式简单且有效,适用于需要针对特定路径禁用过滤器的场景。
最终选择
经过测试,方案三是最有效的解决方案。它通过简单的条件判断实现了对不同 URL 前缀的过滤器应用,避免了复杂的配置和潜在的冲突问题。