Spring Security Reactive WebFilterChainProxy 仅调用单个过滤器链

Posted

技术标签:

【中文标题】Spring Security Reactive WebFilterChainProxy 仅调用单个过滤器链【英文标题】:Spring Security Reactive WebFilterChainProxy only calling a single filter chain 【发布时间】:2018-12-13 10:18:00 【问题描述】:

我需要为基于 Webflux 的应用程序添加安全性,并且我的要求意味着我需要添加多个过滤器链。但是,WebFilterChainProxy 的当前实现使用 Flux.filterWhen(...),如果我正确阅读文档,它将只返回链中的第一个匹配项。

鉴于上述情况,我有三个问题:-

    我的react知识非常有限,谁能确认一下我对filterWhen的理解是否正确?

    如果是这样,谁能提出一种方法让多个过滤器链在新的 Spring Security 5 反应模型中工作?

    如果我误解了 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,但我只得到一个匹配的过滤器。我需要找到一种方法来返回所有匹配的过滤器。

有人可以帮忙吗?

【问题讨论】:

看起来 github.com/spring-projects/spring-security/issues/5395 是 Spring Security 上这个问题的错误 【参考方案1】:

我终于能够通过使用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();

【讨论】:

最后,我实际上做了一些非常相似的事情,但没有作为答案发布,因为它实际上有细微的不同。使用您描述的方法(以及我实现的方法),当我实际想要应用多个过滤器链时,只会应用一个过滤器链。我现在将添加我自己的答案,但感谢您的回复!【参考方案2】:

我在这里回答我自己的问题,希望它可以帮助其他人的理解。

    我的反应知识非常有限,谁能确认我对 filterWhen 的理解是否正确?

是的,我这里的理解是正确的,Flux.filterWhen(...) 只会返回第一个匹配的项目。

    如果是这样,任何人都可以提出一种让多个过滤器链在新的 Spring Security 5 反应模型中工作的方法吗?

在 Spring Security 5 的响应式部分中,多个过滤器链“工作”开箱即用,它们只是以相互排斥的方式工作,例如使用Flux.filterWhen(...),只会应用一个过滤器。

    如果我误解了 filterWhen 方法的工作原理,谁能提出任何建议,为什么只处理我的一个过滤器链?

请参阅上面 2. 的答案。

从更广泛的角度来看,我最初的要求是拥有多个链,其中将应用多个链,但鉴于已经概述的限制,这根本是不可能的。我必须修改我们正在做的事情,以便它与框架一起工作而不是反对它。

我们仍然需要多个过滤器链,因为不同流的安全要求不同,我们最终以与@KRam 答案中所述类似的方式使用相同的ServerWebExchangeMatchers。

【讨论】:

以上是关于Spring Security Reactive WebFilterChainProxy 仅调用单个过滤器链的主要内容,如果未能解决你的问题,请参考以下文章

spring security reactive - 如何调试“无效凭据”错误?

Spring Security Reactive WebFilterChainProxy 仅调用单个过滤器链

使用 Spring Security OAuth 时 Spring Boot Reactive WebClient “serverWebExchange must be null”

Spring boot加载REACTIVE程序过程

Spring Boot Reactive Streams

Spring 5 Reactive - WebExceptionHandler 没有被调用