Spring Security Reactive WebFilterChainProxy вызывает только одну цепочку фильтров - PullRequest
0 голосов
/ 05 июля 2018

Мне нужно добавить защиту в приложение, основанное на Webflux, и у меня есть требования, которые означают, что мне нужно добавить несколько цепочек фильтров. Однако в текущей реализации WebFilterChainProxy используется Flux.filterWhen(...), который, если я правильно читаю документы, будет возвращать только первое совпадение в цепочке.

Учитывая вышеизложенное, у меня есть три вопроса: -

  1. Мои знания о реакции очень ограничены, может ли кто-нибудь подтвердить, правильно ли мое понимание того, что filterWhen делает?

  2. Если да, может ли кто-нибудь предложить способ заставить несколько цепочек фильтров работать в новой реактивной модели Spring Security 5?

  3. Если я неправильно понял, как работает метод filterWhen, кто-нибудь может предложить какие-либо соображения, почему обрабатывается только одна из моих цепочек фильтров?

Способ добавления фильтров в цепочку заключается в нескольких методах настройки, помеченных @Order, аналогично блоку кода ниже.

@Configration
@EnableWebFluxSecurity
public class SecurityConfig
    ...
    @Bean
    @Order(1)
    SecurityWebFilterChain chain1(ServerHttpSecurity http) {
        return http.httpBasic().disable()......
    }

    @Bean
    @Order(2)
    SecurityWebFilterChain chain2(ServerHttpSecurity http) {
        return http.httpBasic().disable()......
    }

    @Bean
    @Order(3)
    SecurityWebFilterChain chain3(ServerHttpSecurity http) {
        return http.httpBasic().disable()......
    }
    ...
}

Когда я отлаживаю приложение, я вижу, что все три фильтра были добавлены в WebFilterChainProxy, но я всегда получаю только один соответствующий фильтр. Мне нужно найти способ вернуть все подходящие фильтры.

Может кто-нибудь помочь, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

Я отвечаю на свои собственные вопросы здесь в надежде, что это поможет пониманию других.

  1. Мои знания о реакции очень ограничены, может кто-нибудь подтвердить, правильно ли я понимаю, что фильтр делает?

Да, мое понимание здесь верно, Flux.filterWhen(...) вернет только первый соответствующий элемент.

  1. Если да, может ли кто-нибудь предложить способ заставить несколько цепочек фильтров работать в новой реактивной модели Spring Security 5?

В Reactive частях Spring Security 5 несколько «цепочек» фильтров работают «из коробки», они просто работают взаимоисключающим образом, например, только один фильтр будет применен при использовании Flux.filterWhen(...).

  1. Если я неправильно понял, как работает метод filterWhen, кто-нибудь может предложить какие-либо соображения, почему обрабатывается только одна из моих цепочек фильтров?

См. Ответ на 2. выше.

С более широкой точки зрения, мое первоначальное требование состояло в том, чтобы иметь несколько цепочек, где было бы применено более одной цепочки, но, с учетом уже изложенных ограничений, это просто невозможно. Мне пришлось изменить то, что мы делали, чтобы оно работало с фреймворком, а не против него.

Нам по-прежнему требовалось несколько цепочек фильтров, поскольку требования безопасности были разными для разных потоков, и в итоге мы использовали одни и те же ServerWebExchangeMatchers аналогично тому, как описано в ответе @KRam.

0 голосов
/ 21 августа 2018

Мне удалось окончательно решить эту проблему с помощью ServerWebExchangeMatchers . Мой вариант использования включал включение базовой аутентификации при доступе к конечным точкам Spring Actuator и отсутствие аутентификации на других путях. Я смог сделать это с помощью следующего кода:

@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity httpSecurity) 
{
    httpSecurity
            .csrf().disable()
            .logout().disable()
            .formLogin().disable();


 httpSecurity.securityMatcher(ServerWebExchangeMatchers.pathMatchers("/actuator/**"))
            .httpBasic()
            .and()
            .authorizeExchange()
            .pathMatchers("/actuator/**")
            .hasRole(ACTUATOR_ADMIN_ROLE);

    return httpSecurity.build();
}
...