在Kotlin流中使用Reactive SecurityConextHolder [英] Using ReactiveSecurityContextHolder inside a Kotlin Flow

查看:17
本文介绍了在Kotlin流中使用Reactive SecurityConextHolder的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Kotlin开发一个Spring Boot(2.2)项目,使用CouchDB作为(反应式)数据库,因此使用异步DAO(挂起函数或返回流的函数)。我正在尝试设置WebFlux,以便也拥有异步控制器(再次声明,我希望返回FLOWS,而不是Flux)。但我在从ReactiveSecurityContextHolder检索我的安全上下文时遇到问题。

根据我所读到的,与使用ThreadLocal存储它的SecurityContextHolder不同,ReactiveSecurityContextHolder依赖于这样一个事实,即Spring在订阅我的反应链的同时,也将该上下文存储在这个链中,从而允许我从链中调用ReactiveSecurityContextHolder.getContext()

问题是我必须在某个时候将Mono<SecurityContext>转换为流,这会使我的SecurityContext松散。所以我的问题是:有没有办法让Spring Boot控制器在从我的逻辑中的ReactiveSecurityContextHolder检索安全上下文的同时返回流?基本上,简化后应该是这样的:

@GetMapping
fun getArticles(): Flow<String> {
    return ReactiveSecurityContextHolder.getContext().flux().asFlow() // returns nothing
}
请注意,如果我直接返回Flux(跳过.asFlow()),或者在末尾添加.single().toList()(因此使用suspend fun),那么它工作得很好,并且返回我的安全上下文,但这也不是我想要的。我想解决方案是将上下文从Flux(初始反应链从ReactiveSecurityContextHolder)转移到流,但这似乎不是默认完成的。

编辑:以下是显示问题的示例项目:https://github.com/Simon3/webflux-kotlin-sample

推荐答案

您真正尝试实现的是从流内部访问您的Reactor Context。

要做到这一点,一种方法是放松对返回流的需求,改为返回Flux。这使您可以恢复ReactorContext并将其传递给要用于生成数据的流。

@ExperimentalCoroutinesApi
@GetMapping("/flow")
fun flow(): Flux<Map<String, String>> = Mono.subscriberContext().flatMapMany { reactorCtx ->
    flow {
        val ctx = coroutineContext[ReactorContext.Key]?.context?.get<Mono<SecurityContext>>(SecurityContext::class.java)?.asFlow()?.single()
        emit(mapOf("user" to ((ctx?.authentication?.principal as? User)?.username ?: "<NONE>")))
    }.flowOn(reactorCtx.asCoroutineContext()).asFlux()
}

在需要从Suspend方法访问ReactorContext的情况下,您只需从coroutineContext取回它,而不需要进一步的手段:

@ExperimentalCoroutinesApi
@GetMapping("/suspend")
suspend fun suspend(): Map<String,String> {
    val ctx = coroutineContext[ReactorContext.Key]?.context?.get<Mono<SecurityContext>>(SecurityContext::class.java)?.asFlow()?.single()
    return mapOf("user" to ((ctx?.authentication?.principal as? User)?.username ?: "<NONE>"))
}

这篇关于在Kotlin流中使用Reactive SecurityConextHolder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆