【问题标题】:How to get public keys in a non blocking manner如何以非阻塞方式获取公钥
【发布时间】:2020-10-08 10:38:42
【问题描述】:

根据文档,签名密钥解析器可以动态获取密钥:https://github.com/jwtk/jjwt#signing-key-resolver

以下代码确实调用了一个 kotlin 挂起函数,该函数以非阻塞方式检索公钥:

val parser =
            Jwts.parserBuilder()
                .setSigningKeyResolver(object : SigningKeyResolverAdapter() {
                    override fun resolveSigningKey(header: JwsHeader<out JwsHeader<*>>, claims: Claims?): Key {
                        return runBlocking {
                            retrievePublicKey(header["kid"])
                        }
                    }
                }).build()
        val claims = parser.parseClaimsJws(jwtString).body

这里是挂起函数的定义

suspend fun retrievePublicKey(key:String):PublicKey {
...
}

问题是这段代码需要阻塞线程(runBlocking)。否则无法正常工作。

所有其他异步框架(rxjava、listenablefuture、completablefuture 等)也存在这一挑战

【问题讨论】:

  • build() 方法返回线程安全的JwtParser。我猜resolveSigningKey()方法是在后台线程中调用的(你可以检查它在日志中添加Thread.currentThread()),所以线程可以被阻塞。
  • 我不这么认为:github.com/jwtk/jjwt/blob/… 我认为他们将线程留给我们。

标签: kotlin-coroutines jjwt


【解决方案1】:

貌似jwtk库大部分是同步的,所以不能直接使用suspend来避免阻塞。

您可能应该包装库,以便在设计用于处理阻塞 IO 的 IO 调度程序上完成 parse* 调用。 此外,如果您将 retrievePublicKey 挂起函数设计为依赖调用者来处理线程,则可以使其在同一线程中执行必要的阻塞 IO,而不会消耗更多资源。

val parser = /* create parser with runBlocking */
val claims = withContext(Dispatchers.IO) {
    // This will end up synchronously calling runBlocking, if the
    //  suspend function does not explicitly switch context it will do its work
    //  on the same thread.
    parser.parseClaimsJws(jwtString)
}.body

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多