您能解释处理@PreAuthorize("hasRole('ADMIN')")
的建议在Reactive应用程序中检索SecurityContext
的位置吗?
以下Spring Security示例很好地说明了这种用法:https://github.com/spring-projects/spring-security/tree/5.0.0.M4/samples/javaconfig/hellowebflux-method
在检查了Spring Security Webflux源代码之后,我发现了SecurityContextRepository
的一些实现,但是load方法需要ServerWebExchange
作为参数。
我正在尝试了解如何在标准服务中替换SecurityContextHolder.getContext().getAuthentication()
调用(因为ThreadLocal
不再是Reactive Application中的选项),但我不明白如何替换它拨打SecurityContextRepository
,但ServerWebExchange
没有参考。
答案 0 :(得分:6)
你是对的,ThreadLocal
不再是一个选项,因为请求的处理不依赖于特定的线程。
目前,Spring Security将身份验证信息存储为ServerWebExchange
属性,因此与当前请求/响应对相关联。但是,当您无法直接访问当前交易所时,仍需要该信息,例如@PreAuthorize
。
身份验证信息存储在Reactive管道中(可以从Mono
或Flux
访问),这是一个非常有趣的Reactor功能 - 管理与特定{{1}相关联的上下文(在Web应用程序中,HTTP客户端正在从服务器提取数据并且这样做)。
我不知道相当于Subscriber
或某种从上下文中获取身份验证信息的快捷方法。
详细了解Reactor Context feature in the reference documentation。 您还可以看到that being used in Spring Security here的示例。
答案 1 :(得分:5)
ReactiveSecurityContextHolder
以反应方式提供身份验证,类似于SecurityContextHolder
。
它的getContext()
方法提供了Mono<SecurityContext>
,就像SecurityContextHolder.getContext()
提供了SecurityContext
一样。
ReactiveSecurityContextHolder
.getContext()
.map(context ->
context.getAuthentication()
答案 2 :(得分:1)
我实现了JwtAuthenticationConverter(kotlin):
val authFilter = AuthenticationWebFilter(ReactiveAuthenticationManager {
authentication: Authentication -> Mono.just(authentication)
})
authFilter.setAuthenticationConverter(jwtAuthenticationConverter)
http.addFilterAt( authFilter, SecurityWebFiltersOrder.AUTHENTICATION)
然后我像这样设置一个SecurityConfig:
first_name = input("enter your first name\n")
last_name = input("enter your last name\n")
first_name = first_name.lower()
last_name = last_name.lower()
def rev(s):
str = ""
for i in s:
str = i + str
return str
first_name = rev(first_name)
last_name = rev(last_name)
first_name = first_name[0].upper() + first_name[1:]
last_name = last_name[0].upper() + last_name[1:]
print(first_name + " " + last_name)
您可以使用此方法自定义AuthenticationConverter,就像我对基于jwt的身份验证所做的那样,以设置所需的身份验证对象。