我正在尝试使用多个安全配置设置我的 Spring Boot 3.0 / Spring Security 6 应用程序。
/oauth/token
应使用/允许/强制执行基本身份验证我遇到的问题是,如果我向
GET
发送带有标头 /test
的 Authorization: Basic xxx
请求,基本身份验证过滤器仍然会接收它。
这就是我到目前为止所拥有的。承载过滤器尚未实现,但为了解决这个问题,我们假设所有其他端点都应该完全开放。如果用户传入基本身份验证标头,如何让他们绕过基本身份验证过滤器?
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(CsrfConfigurer::disable)
.authorizeHttpRequests()
.requestMatchers("/oauth/token").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic(Customizer.withDefaults());
return http.build();
}
比如这个:
private static final String[] RESOURCE_ARGS = new String[]{
"/test/**"
};
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.requestMatchers(RESOURCE_ARGS).permitAll();
http
.csrf(CsrfConfigurer::disable)
.authorizeHttpRequests()
.requestMatchers("/oauth/token").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic(Customizer.withDefaults());
....
}
我花了几个小时迁移到 Spring Security 6。我有 4 种配置,现在可以分享我的经验。
首先,您需要添加
@Bean
中的第二个 SecurityFilterChain
,准备好使用 @Order(1)
和 @Order(2)
来指定它们的顺序。
确保您填写了
requestMatchers
,此方法允许分离安全过滤逻辑,例如,填写 /oauth/token
表示基本身份验证,填写 /test
表示承载。我觉得用/test/**
比较好,可以过滤/test
下的所有路径。
您可能想为这些链添加一些不同的
AuthenticationProvider
,可以用不同的名称创建这样的bean。请注意,只能出现一个 AuthenticationManager
:
@Bean
public AuthenticationManager authenticationManager(HttpSecurity httpSecurity,
AuthenticationProvider basicAuthProvider,
AuthenticationProvider bearerAuthProvider) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder = httpSecurity.getSharedObject(AuthenticationManagerBuilder.class)
.authenticationProvider(basicAuthProvider)
.authenticationProvider(bearerAuthProvider);
return authenticationManagerBuilder.build();
}