Spring security 如何在扩展HikariDataSource的类中访问ReactiveSecurityContextHolder?

Spring security 如何在扩展HikariDataSource的类中访问ReactiveSecurityContextHolder?,spring-security,spring-data-jpa,spring-webflux,multi-tenant,hikaricp,Spring Security,Spring Data Jpa,Spring Webflux,Multi Tenant,Hikaricp,我正在将一个SpringMVC项目迁移到SpringWebFlux。出于几个原因,我们决定继续使用spring-data-jpa,即使我们必须小心阻塞等。我们的应用程序支持多租户,我们这样做的方式是在执行请求之前为连接设置一个特殊的数据库变量。数据库负责其余的工作 下面的类用于应用程序配置文件的spring.datasource.type参数 class-TenantAwareDataSource:HikariDataSource(){ 重写fun getConnection():Connect

我正在将一个SpringMVC项目迁移到SpringWebFlux。出于几个原因,我们决定继续使用
spring-data-jpa
,即使我们必须小心阻塞等。我们的应用程序支持多租户,我们这样做的方式是在执行请求之前为连接设置一个特殊的数据库变量。数据库负责其余的工作

下面的类用于应用程序配置文件的
spring.datasource.type
参数

class-TenantAwareDataSource:HikariDataSource(){
重写fun getConnection():Connection=super.getConnection()。同时{
it.createStatement().use{
execute(“SET tnt_id=”+getTenantId()+“”)
//^使用runBlocking调用,因为内联函数是挂起函数
}
}
fun suspend getTenantId():字符串{
返回Mono.subscriberContext()
.map{context:context->
context.get(“tnt_id”)
}.log().flux().asFlow().toList()[0]
}
}
我们的
getTenantId()
函数是基于
SecurityContext
类工作的,该类使用ThreadLocal来保存值。它是使用来自客户端的JWT通过servlet过滤器填充的。当切换到Spring Webflux时,我们将过滤器更改为
WebFilter
,甚至设法将所需的值注入
ReactiveSecurityContextHolder
,如下所示:

类MyFilter:WebFilter{
覆盖有趣的过滤器(exchange:ServerWebExchange,链:WebFilterChain):Mono{
返回链。过滤器(交换)
.subscriberContext{it.put(“tnt_id”,getTentantFromJWT())}
}
}
在控制器端点中,我们已成功获取存储值:

@GetMapping(“/rsch-test”)
suspend fun reactiveSecurityContextHolderTest():字符串?{
返回ReactiveSecurityContextHolder.getContext().flux().asFlow().toList().toString()
}
但是,这在我们的
tenatawaredatasource
类中是不可能的,因为程序记录:

| onSubscribe([Fuseable] FluxMapFuseable.MapFuseableSubscriber)
| request(64)
| onNext(empty)
| onComplete()
然而,如果将相同的代码置于控制器中,则会发出不同的输出:

| onSubscribe([Fuseable] FluxMapFuseable.MapFuseableConditionalSubscriber)
| request(64)
| onNext(<tenant_id>)
| onComplete()
| onSubscribe([fusable]fluxmapfusable.MapFuseableConditionalSubscriber)
|请求(64)
|onNext()
|onComplete()
我猜这是因为被动上下文没有传播到这个类。我意识到使用ThreadLocal不是一个选项,因为:

  • 不能保证Web筛选器将与SQL变量设置在同一线程上运行
  • 不能保证一次只能在一个线程上运行一个作业。可能会有“碰撞”
  • 你对此有什么想法吗?也许我错过了一些解决办法。 多谢各位

    编辑:


    添加了@Toerktumlare请求的有关尝试检索ReactiveSecurityContext的代码。

    TenantWaredataSource类,Mono返回空。我猜发生这种情况是因为被动上下文没有传播到这个类
    rhis代码在哪里?然后,我想知道为什么它没有传播?我已经完成了这个示例。希望现在更容易理解。你还没有透露这是如何被称为。我不知道Kotlin,但在尝试使用当前连接的上下文时,必须确保您处于被动上下文中。如果您不在被动上下文中,它将是空的。查看文档中的上下文示例,您必须在flatMap中才能访问上下文