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

Spring WebFlux中如何通过ReactiveSecurityContextHolder获取JWT?

如何在Spring WebFlux中通过ReactiveSecurityContextHolder获取JWT令牌

首先明确:在Spring WebFlux的响应式模型中,绝对不能使用block()等阻塞方法,这会破坏响应式链,导致ReactiveSecurityContextHolder的上下文丢失,同时违反非阻塞设计原则,这也是你遇到异常或空值的核心原因。

ReactiveSecurityContextHolder的上下文绑定在Reactor流的Context中,只有在Mono/Flux的操作链内才能正确访问,以下是正确的实现方式:

1. 封装可复用的上下文获取工具

编写工具类统一处理JWT认证信息的获取:

public class ReactiveSecurityUtils {
    // 获取当前请求的JWT认证令牌
    public static Mono<JwtAuthenticationToken> getCurrentJwtAuth() {
        return ReactiveSecurityContextHolder.getContext()
                .map(SecurityContext::getAuthentication)
                .cast(JwtAuthenticationToken.class);
    }
}

2. 在响应式流中使用

所有需要获取JWT信息的操作必须嵌入Mono/Flux的操作链中,比如在Controller层:

@RestController
public class UserController {
    private static final String USER_MAIN_ID_TOKEN = "user_main_id";

    @GetMapping("/user/main-id")
    public Mono<String> getUserMainId() {
        return ReactiveSecurityUtils.getCurrentJwtAuth()
                .map(jwtAuth -> jwtAuth.getTokenAttributes().get(USER_MAIN_ID_TOKEN).toString());
    }
}

在Service层复用同样要保持响应式:

@Service
public class UserService {
    private static final String USER_MAIN_ID_TOKEN = "user_main_id";

    public Mono<User> getCurrentUser() {
        return ReactiveSecurityUtils.getCurrentJwtAuth()
                .map(jwtAuth -> (String) jwtAuth.getTokenAttributes().get(USER_MAIN_ID_TOKEN))
                .flatMap(this::getUserById); // 调用其他响应式业务方法
    }

    private Mono<User> getUserById(String userId) {
        // 模拟从数据库获取用户的响应式操作
        return Mono.just(new User(userId));
    }
}

3. 为什么之前的方式无效?

  • 非响应式的Supplier无法访问Reactor流的Context,直接调用get()会因上下文未绑定返回null
  • 使用block()会强制中断响应式链,导致上下文丢失,同时触发WebFlux的阻塞操作异常
  • 所有依赖ReactiveSecurityContextHolder的操作,必须处于Mono/Flux的操作链中,才能继承当前请求的上下文

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 22:03:23