graphql-java嵌套的解析器在具有不同Spring安全上下文的不同线程中执行

时间:2019-04-09 08:27:47

标签: java spring kotlin spring-security graphql-java

我正在使用graphql-java,它在单独的线程中执行不同的嵌套解析器。

我在Spring Security上有一个自定义过滤器,该过滤器从Authorization Header中解析Bearer令牌,并将其添加到当前Spring Security上下文中。

我暂时能够通过监听ContextRefreshedEvent并将策略强制为Global来解决该问题,如您在此处看到的那样:

    @EventListener
    fun setupSecurityContext(event: ContextRefreshedEvent) {
        SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_GLOBAL)
    }

我对此解决方案不满意,因为当我想接收作为解析器上的参数传递的令牌时,必须使用全局静态调用来访问解析器上的令牌。

SecurityContextHolder.getContext().authentication.principal

我认为这不是一个好习惯。我猜一个请求的数据可以通过不同的线程暴露给另一个用户。

1 个答案:

答案 0 :(得分:1)

我在使用改造客户端时遇到了同样的问题。 我只需要像这样将 spring 委托执行程序设置为 okhttp 调度程序:

@Bean
DelegatingSecurityContextExecutorService dispatcherExecutor() {
    return new DelegatingSecurityContextExecutorService(
            new ThreadPoolExecutor(
                    0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
                    new SynchronousQueue<>(), Util.threadFactory("OkHttp Dispatcher", false)
            )
    );
}

@Bean
OkHttpClient okHttpClient() {
    var interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);

    return new OkHttpClient.Builder()
            .connectTimeout(retrofitConnectionTimeout, TimeUnit.SECONDS)
            .readTimeout(retrofitConnectionTimeout, TimeUnit.SECONDS)
            .addInterceptor(interceptor)
            .dispatcher(new Dispatcher(dispatcherExecutor()))
            .build();
}

graphql 怎么样,请看graphql.execution.ExecutorServiceExecutionStrategy。它允许设置graphql异步调用执行器服务,因此您可以在此处传递spring委托执行器服务。