WebFlux+DGS GraphQL:如何在DataFetcher与SchemaDirectiveWiring中获取SecurityContext
在SchemaDirectiveWiring的onField函数中获取Authentication对象的解决方案
在反应式DGS框架环境下,不能通过同步方式(比如block())获取SecurityContext,必须遵循Reactor的响应式上下文传递规则来处理。以下是正确获取Authentication对象的实现方式:
核心实现思路
从ReactiveDgsContext拿到Reactor Context后,通过响应式操作符异步提取SecurityContext,再从中获取Authentication,全程保持响应式链不中断。
修改后的代码示例
DataFetcher<?> authDataFetcher = DataFetcherFactories.wrapDataFetcher(originalFetcher, ((dataFetchingEnvironment, value) -> { ReactiveDgsContext context = ReactiveDgsContext.from(dataFetchingEnvironment); if (context != null) { ContextView reactiveContext = context.getReactorContext(); // 从Reactor Context中异步提取SecurityContext与Authentication return reactiveContext.getOrEmpty(SecurityContext.class) .map(SecurityContext::getAuthentication) .flatMap(authentication -> { // 在这里编写你的权限校验或业务逻辑 // 示例:打印认证信息 System.out.println("当前认证用户: " + authentication.getName()); // 处理完成后返回原数据,或根据需求修改返回值 return Mono.just(value); }) // 处理未获取到认证信息的场景 .switchIfEmpty(Mono.error(new RuntimeException("未获取到合法的认证信息"))); } return Mono.error(new IllegalStateException("无法获取ReactiveDgsContext")); }));
关键注意事项
- 禁止使用block():同步阻塞会破坏Reactor上下文传递机制,导致无法获取到SecurityContext
- 使用getOrEmpty():避免上下文不存在时直接抛出异常,提升代码健壮性
- 保持响应式链:所有逻辑必须在
Mono/Flux的操作符(如map、flatMap)内完成,确保上下文能正确传递 - 确认SecurityContext配置:确保Spring Security的反应式配置(如
@EnableWebFluxSecurity)已正确将SecurityContext注入到Reactor Context中
内容的提问来源于stack exchange,提问作者Henry Hargreaves
相关产品推荐
相关产品推荐

