当前位置: 首页 > 知识库问答 >
问题:

在Kotlin流中使用ReactiveSecurityContextHolder

凌修伟
2023-03-14

我正在使用静态编程语言进行Spring Boot(2.2)项目,CouchDB作为(反应性)数据库,结果是异步DAO(挂起函数或返回Flow的函数)。我试图设置WebFlux,以便也有异步控制器(同样,我想返回流,而不是Flux)。但是我在从ReactiveSecurityContextHolder检索我的安全上下文时遇到了麻烦。

据我所知,SecurityContextHolder使用ThreadLocal来存储它,ReactiveSecurityContextHolder依赖于这样一个事实,Spring在订阅我的反应链时,也将该上下文存储在这个链中,从而允许我调用ReactiveSecurityContextHolder。从链中获取上下文()

问题是我得把我的单声道

@GetMapping
fun getArticles(): Flow<String> {
    return ReactiveSecurityContextHolder.getContext().flux().asFlow() // returns nothing
}

请注意,如果我直接返回通量(跳过.asFlow()),或添加。single()。toList()最后(因此使用了一个suspend fun),然后它就可以正常工作了,并返回了我的安全上下文,但这又不是我想要的。我猜解决方案是将上下文从流量(从ReactiveSecurityContextHolder的初始反应链)转移到流,但它似乎不是默认完成的。

编辑:下面是一个示例项目,展示了这个问题:https://github.com/Simon3/webflux-kotlin-sample


共有1个答案

颛孙子民
2023-03-14

您真正要实现的是从Flow内部访问ReactorContext。

这样做的一种方法是放松对返回Flow的需求,而是返回Flux。这允许您恢复ReactorContext并将其传递给要用于生成数据的Flow。

@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()
}

在需要从挂起方法访问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>"))
}
 类似资料:
  • 如何在中的每个项中使用? 我得xml: null

  • 我想利用一个简单的流从http服务收集一些额外的数据,并用这些结果来增强我的数据对象。下面说明了这一想法: 我有一个问题,要理解流的本质和流内部的物化/未来之间的机制和区别。 以下想法并没有向我解释: null

  • 我开玩笑地增加,减少物品数量。我想算数。文本加上“T”字符。当我试图编写这样的代码时。错误代码:java.lang.NumberFormatException:对于输入字符串:“1T”如何解决此问题?有人能帮忙吗??

  • 问题内容: 我面临的问题是回报。当用于仅接受非空类型的模拟方法时,它将导致引发“应该不为空”异常。 模拟方法: 问题答案: 有两种可能的解决方法: 另一个解决方法是 这是有关此主题的更多讨论,其中首先提出了解决方法。

  • 本文向大家介绍Android在Kotlin中更好地使用LitePal,包括了Android在Kotlin中更好地使用LitePal的使用技巧和注意事项,需要的朋友参考一下 Kotlin 是一个用于现代多平台应用的静态编程语言,由 JetBrains 开发。 Kotlin可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行。 Kotlin已正式成为Android官

  • 我的处理器中有一个简单的注释,如下所示: 这适用于java文件,但一旦我将文件转换为kotlin,注释的导入就不再有效。为什么? 我需要改变什么才能让他的注释也在Kotlin中工作?从文档中,我可以看到kotlin与java注释100%兼容,所以我有点困惑这里有什么问题...如果处理器不工作,需要调整以与kotlin一起工作,我会理解,但我不知道为什么导入本身不工作... 我说的图书馆在这里:ht