Использование двух или более SecurityFilterChains с Spring Security 6 не работает должным образом, вызывается только одна цепочка.
У меня проблемы с получением двухSecurityFilterhain
работают вместе друг с другом с использованием Spring Security 6. Для одного из моих путей к конечной точке (/v1/transactions/**
) Я хочу, чтобы пользователь авторизовался с помощью Oauth2, а для другого пути конечной точки () требуется базовая аутентификация. Только одна из конфигураций работает должным образом в зависимости от того, какая@Order()
у них есть.
С двумя нижеSecurityFilterChain
конфигурации. Я могу отправлять запросы на использование базовой аутентификации, но не делать запросы на использование Oauth2, что просто дает мне 401 Access Denied.
Если я изменю порядок такbasicAuthSecurityFilterChain
получает@Order(2)
иoauth2SecurityFilterChain
получает@Order(1)
тогда я могу звонить с использованием OAauth2, но не звонить с использованием Basic Auth, что затем дает мне 401 Access Denied.
Я не уверен, почему я сталкиваюсь с таким поведением, поскольку в документации говорится, что вызов SecurityFilterChain определяется на основе пути, а пути для базовых ресурсов auth и oauth2 различны (/v1/transaction/**
против/v1/info
).
@EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true)
@EnableWebSecurity
@Configuration
public class BasicAuthSecurity {
public AuthenticationManager authProviderManager() { //omitted code) }
@Bean
@Order(1)
public SecurityFilterChain basicAuthSecurityFilterChain(HttpSecurity http) throws Exception {
return http
.authenticationManager(authProviderManager())
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(POST, "/v1/info", "/v1/info/{user}").hasRole("user")
.anyRequest().authenticated()
)
.httpBasic(withDefaults())
.build();
}
}
А для OAuth2 SecurityFilterChain я использую это:
@EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true)
@EnableWebSecurity
@Configuration
public class Oauth2Security {
@Bean
@Order(2)
public SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(POST, "/v1/transaction/**")
.hasAnyRole("poweruser", "admin")
.anyRequest().authenticated()
)
.oauth2ResourceServer()
.jwt()
.and().and().build();
}
}
1 ответ
вам не хватаетsecurityMatcher
в первой цепочке фильтров в@Order
. Так просто :/
// Applies only to the specified security-matchers
@Bean
@Order(1)
public SecurityFilterChain basicAuthSecurityFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher("/v1/info/**");
return http
.authenticationManager(authProviderManager())
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(POST, "/v1/info", "/v1/info/{user}").hasRole("user")
.anyRequest().authenticated()
)
.httpBasic(withDefaults())
.build();
}
// this one has lowest order and no security matcher
// => behaves as default when higher order ones security matchers did not match
@Bean
@Order(2)
public SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(POST, "/v1/transaction/**")
.hasAnyRole("poweruser", "admin")
.anyRequest().authenticated()
)
.oauth2ResourceServer()
.jwt()
.and().and().build();
}