我正在使用Spring Security作为依赖项构建一个Sping Boot v3.1.1
应用程序。
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.1'
id 'io.spring.dependency-management' version '1.1.0'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
}
字符串
我已经创建了两个自定义过滤器,希望它们在Spring Security过滤器之后运行(在链中的最后一个):
@Order(1)
@Component
public class DeviceFilter extends OncePerRequestFilter {}
@Order(2)
@Component
public class MdcFilter extends OncePerRequestFilter {}
型
他们正在工作,但我不能确认订单是否正确。
我试过这个:
@Configuration
@EnableWebSecurity(debug = true)
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.formLogin(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable) // Removes CsrfFilter
.logout(AbstractHttpConfigurer::disable) // Removes LogoutFilter
.rememberMe(AbstractHttpConfigurer::disable) // Removes RememberMeAuthenticationFilter
.requestCache(RequestCacheConfigurer::disable) // Removes RequestCacheAwareFilter
.cors(withDefaults()) // Adds CorsFilter
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.oauth2ResourceServer(oauth2 -> oauth2.jwt(withDefaults()));
return http.build();
}
}
型
控制台中的结果:
Security filter chain: [
DisableEncodeUrlFilter
WebAsyncManagerIntegrationFilter
SecurityContextHolderFilter
HeaderWriterFilter
CorsFilter
BearerTokenAuthenticationFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
AuthorizationFilter
]
型
如果您注意到,我的两个自定义过滤器不存在,但它们以某种方式工作。
我认为Spring Security筛选器独立于自定义筛选器,并且这些筛选器不会添加到它们所管理的筛选器数组中。我不确定,我不是这方面的Maven。
此外,我已经尝试把日志内我的两个自定义过滤器,以检查顺序。他们很好。
09:05AM INFO DeviceFilter : {} DeviceFilter!!!!!!!
09:05AM INFO MdcFilter : {} MdcFilter!!!!!!!
型
但到目前为止,我不能保证它们在Spring Security过滤器之后运行。* 原因是我只希望在用户成功通过身份验证并通过所有Spring Security检查的情况下才运行它们。*
我尝试过的另一件事是在securityFilterChain()
方法中添加过滤器,这意味着我的过滤器不再实现@Order
和@Component
:
@Configuration
@EnableWebSecurity(debug = true)
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// .......
// ......
.addFilterAfter(new DeviceFilter(), AuthorizationFilter.class);
.addFilterAfter(new MdcFilter(), DeviceFilter.class);
return http.build();
}
}
型
控制台中的结果:
Security filter chain: [
DisableEncodeUrlFilter
WebAsyncManagerIntegrationFilter
SecurityContextHolderFilter
HeaderWriterFilter
CorsFilter
BearerTokenAuthenticationFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
AuthorizationFilter
DeviceFilter // <=================
MdcFilter // <=================
]
型
我更愿意坚持使用@Order和@Component方法,因为这对我来说更容易。
在其他线程中,他们讨论了如何设置顺序。
- Controlling the order of non-security Filters in a Spring Boot app using Spring Security
- Filter order in spring-boot
我的问题是如何确认我的订单(使用@Order和@Component)是正确的,并且它们在Spring Security过滤器之后运行?
提前感谢,并感谢任何推动这一点。
1条答案
按热度按时间cdmah0mi1#
你的猜测是正确的。Spring安全(即
FilterChainProxy
)使用的过滤器内部有自己的过滤器链(即SecurityFilterChain
),这些内部过滤器的顺序不会受到@Order
的影响。@Order
只对标准servletFilter
bean(包括FilterChainProxy
)有影响。通过分析源代码,
ServletContextInitializerBeans
负责对所有基于@Order
的标准servletFilter
bean进行排序。然后,它会根据这个排序顺序将Filter
逐个注册到servlet容器。因此,您可以通过定义
CommandLineRunner
来间接确认Filter
订单,CommandLineRunner
将在应用程序启动时执行以打印订单。例如:字符串
它会打印出类似这样的内容:
型