如何从DataFetcher中获取SecurityContext(WebFlux + DGS GraphQL)

tjjdgumg  于 2023-05-22  发布在  Spring
关注(0)|答案(1)|浏览(113)

我想知道是否可以从SchemaDirectiveWiring中包含的onField函数中获得Authentication
我曾经研究过使用ReactiveSecurityContextHolderSecurityContextHolder.getContext().getAuthentication()ReactiveSecurityContextHolder.getContext().block().getAuthentication(),但都返回null(这是有意义的,因为它是在异步线程中调用的)。
因此,我考虑使用[ReactiveDgsContext][1],这看起来很有希望,因为在调试代码时,我可以在reactorContext中看到有一个SecurityContext键/值,但我不知道如何正确访问/检索它。
目前,我的代码看起来如下:

DataFetcher<?> authDataFetcher = DataFetcherFactories
                .wrapDataFetcher(originalFetcher, ((dataFetchingEnvironment, value) -> {
                    ReactiveDgsContext context = ReactiveDgsContext.from(dataFetchingEnvironment);
                    if(context != null){
                        ContextView reactiveContext = context.getReactorContext();
...
                    }

任何帮助将不胜感激!

t8e9dugd

t8e9dugd1#

我无法找到一种方法来从ReactiveDgsContext对象中获取身份验证,但作为一种解决方法,我创建了一个自定义上下文。

public record CustomContext(ServerRequest webExchange, SecurityContext securityContext) {
}

然后注册如下:

@Configuration
public class DgsConfiguration {

    @Bean
    public DgsReactiveCustomContextBuilderWithRequest<CustomContext> dgsReactiveCustomContextBuilder() {
        return (map, httpHeaders, serverRequest) -> ReactiveSecurityContextHolder.getContext()
                .map(securityContext -> new CustomContext(serverRequest, securityContext))
                .defaultIfEmpty(new CustomContext(serverRequest, null));
    }

}

然后,您可以按如下方式访问它:

DataFetcher<?> authDataFetcher = DataFetcherFactories
                .wrapDataFetcher(originalFetcher, ((dataFetchingEnvironment, value) -> {
                    ReactiveDgsContext context = ReactiveDgsContext.from(dataFetchingEnvironment);
                    if (context != null) {
                        CustomContext customContext = (CustomContext) context.getCustomContext();
                        if (customContext != null) {
                            Authentication authentication = customContext.securityContext().getAuthentication();
                            ....
                        }
                    }

或者,您也可以从头文件中获取JWT令牌并再次检查它,但考虑到这已经完成,我不想再做一次(使用Firebase,因此将多次调用oauth服务器)。
感谢ChatGPT在这方面的帮助--如果有人有更好的方法来做到这一点(也许使用ReactiveDgsContext,我会有兴趣看看它!)

相关问题