3

I am using graphql-java, and it executes the different nested resolvers in separate threads.

I have a custom filter on spring security that parses the Bearer token from the Authorization Header and adds that to the current spring security context.

I was temporarily able to solve the issue by listening to the ContextRefreshedEvent and forcing the strategy to Global, as you can see here:

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

I am not happy with this solution because I have to access the tokens on the resolvers with a global static call when I would like to receive it passed as a parameter on the resolver.

SecurityContextHolder.getContext().authentication.principal

I believe this is not a good practice. I guess the data from one request can be exposed to another user by a different thread.

1 Answer 1

2

I faced the same issue using a retrofit client. All I need is just to set spring delegating executor to the okhttp dispatcher like this:

@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();
}

What about graphql, please look at graphql.execution.ExecutorServiceExecutionStrategy. It allows to setup graphql async calls executor service, so you can pass spring delegating executor service here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.