Использование двух или более 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();
    }
Другие вопросы по тегам