Spring security @PreAuthorize如何在反应式应用程序中工作,或者如何在没有ThreadLocal的情况下生存?

Spring security @PreAuthorize如何在反应式应用程序中工作,或者如何在没有ThreadLocal的情况下生存?,spring-security,spring-webflux,Spring Security,Spring Webflux,您能否解释一下,通知处理@PreAuthorize(“hasRole('ADMIN')”)在反应式应用程序中从何处检索SecurityContext 下面的Spring Security示例很好地说明了这种用法: 在检查Spring Security Webflux源代码之后,我发现了一些SecurityContextRepository的实现,但是加载方法需要ServerWebExchange作为参数 我试图理解如何替换标准服务中的调用SecurityContextHolder.getCont

您能否解释一下,通知处理
@PreAuthorize(“hasRole('ADMIN')”)
在反应式应用程序中从何处检索
SecurityContext

下面的Spring Security示例很好地说明了这种用法:

在检查Spring Security Webflux源代码之后,我发现了一些
SecurityContextRepository
的实现,但是加载方法需要
ServerWebExchange
作为参数


我试图理解如何替换标准服务中的调用
SecurityContextHolder.getContext().getAuthentication()
(因为
ThreadLocal
不再是被动应用程序中的选项),但是我不明白如何用调用
SecurityContextRepository
来代替它,而不在
ServerWebExchange

上引用您是对的,
ThreadLocal
不再是一个选项,因为请求的处理与特定线程无关

目前,Spring Security将身份验证信息存储为
ServerWebExchange
属性,与当前请求/响应对紧密相连。但是,当您无法直接访问当前exchange时,仍然需要这些信息,如
@PreAuthorize

身份验证信息存储在反应式管道本身中(因此可以从
Mono
Flux
访问),这是一个非常有趣的反应器功能-管理与特定
订阅者
关联的上下文(在web应用程序中,HTTP客户机从服务器提取数据,并执行类似操作)

我不知道有一种等价的
SecurityContextHolder
,或者从上下文中获取身份验证信息的快捷方法

了解更多关于。
您还可以看到一个示例。

我实现了一个JwtAuthenticationConverter(kotlin):

您可以使用此方法自定义AuthenticationConverter,就像我对基于jwt的身份验证所做的那样,以设置所需的身份验证对象。

以反应式方式提供身份验证,类似于

它的方法提供了一个,就像提供了一个
SecurityContext

ReactiveSecurityContextHolder
                    .getContext()
                    .map(context ->
                            context.getAuthentication()

返回Mono/Flux必须返回到Spring(在控制器中),以便填充上下文。请参阅
val authFilter = AuthenticationWebFilter(ReactiveAuthenticationManager {
    authentication: Authentication -> Mono.just(authentication)
})
authFilter.setAuthenticationConverter(jwtAuthenticationConverter)

http.addFilterAt( authFilter, SecurityWebFiltersOrder.AUTHENTICATION)
ReactiveSecurityContextHolder
                    .getContext()
                    .map(context ->
                            context.getAuthentication()