我遇到了Quarkus和smallray - jwt的问题。我有一个动态查找消费服务的(私有)密钥来解密令牌,以及从发布服务的(公共)密钥来验证令牌的方案。
然而,无论我如何尝试,我都无法让它在可以进行数据库调用的上下文中执行。它抛出了一个javax.enterprise.context.ContextNotActiveException
,我明白这意味着什么,但我不能让它消失。看起来JWT解析工厂可能没有在工作线程/活动上下文中执行。
文档建议创建自定义工厂,但这并没有真正帮助。JWT工厂的解析方法在I/O线程中运行,并且不是响应性的,因此无论如何也不会阻塞。
我尝试扩展io.quarkus.smallrye.jwt.runtime.auth.JWTAuthMechanism
并使用我的@Alternate
注释实现覆盖authenticate
方法。这将返回Uni<>
,但无论我做什么,我都无法从那里获得在活动上下文中运行的键解析方法。
这是源存储库。这里是JWT身份验证机制。KeyResolver(实际使用活动记录模式查找键)在这里。
问题是:我如何在工作线程的活动上下文中运行一些东西,当它在安全决议内部被调用时?
有几个层次可以解决这个问题。第一个是使用quarkus.smallrye-jwt.blocking-authentication=true
使JWT解析阻塞。
下一件事是实现,正如文档所说,JWTCallerPrincipalFactory。既然这发生在Worker线程上,那么调用DB来获取我的键就没有问题了。
参见:CustomJWTCallerPrincipalFactory和KeyResolver的自定义JWTConsumer
最后,需要将从DB查找键的注册中心(调用活动记录的bean#方法)标记为@Transactional
。
看到:StoredKeyPairRegistry