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”