You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Webflux+JJWT解析JWT时Blocking Call问题解决求助

问题描述

使用Kotlin、Spring Webflux和JJWT 0.12.6开发JWT生成与解析功能时,BlockHound检测到解析流程存在阻塞调用,根源是SecureRandom.nextBytes()触发了文件IO阻塞。堆栈信息显示阻塞发生在JJWT内部静态类初始化阶段(EcdhKeyAlgorithm、Randoms等类的加载),JWT生成功能已通过指定NativePRNGNonBlocking类型的SecureRandom解决阻塞问题,但解析流程暂无对应配置方式。

当前解析代码:

val claims: Jws<Claims> = Jwts.parser()
    .verifyWith(Keys.hmacShaKeyFor(secret.toByteArray()))
    .build()
    .parseSignedClaims(token)
解决方案

方法1:全局配置非阻塞SecureRandom(推荐)

JJWT支持全局设置SecureRandom实例,所有涉及随机数生成的逻辑都会复用该实例,从根源避免阻塞:

  1. 创建全局非阻塞SecureRandom实例:
private val nonBlockingSecureRandom = SecureRandom.getInstance("NativePRNGNonBlocking")
  1. 在应用启动阶段设置全局实例(比如通过@PostConstruct或Webflux启动钩子):
import io.jsonwebtoken.Jwts
import javax.annotation.PostConstruct

@PostConstruct
fun initJJWTSecureRandom() {
    Jwts.setSecureRandom(nonBlockingSecureRandom)
}

设置完成后,JWT生成与解析流程都会使用这个非阻塞的随机数生成器,不会再触发FileInputStream的阻塞调用。

方法2:提前触发静态类初始化(备选)

如果无法全局配置,可在应用启动时提前触发JJWT内部静态类的初始化,将阻塞操作转移到启动阶段(需在非Reactor主线程执行):

import io.jsonwebtoken.Jwts
import reactor.core.publisher.Mono
import reactor.core.scheduler.Schedulers

// 在应用启动类中添加
fun initJJWTOnStartup() {
    Mono.fromCallable {
        // 触发Jwts.parser()的静态初始化
        Jwts.parser().build()
    }.subscribeOn(Schedulers.boundedElastic())
     .subscribe()
}

这种方法仅将阻塞操作转移到启动阶段,后续解析请求不会再触发,但未从根源替换阻塞的SecureRandom,优先级低于方法1。

验证

修改后重新用BlockHound检测,解析接口的阻塞调用应会消失。


内容的提问来源于stack exchange,提问作者suw0n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:14:52