-
Notifications
You must be signed in to change notification settings - Fork 327
Wrong SecurityContext with async-mode-enabled: true results #632
Comments
Thanks for reporting @ncioj10! Just noticed the same thing. The problem is caused by this snippet in asyncContext.start(
() -> {
FutureExecutionResult futureResult = invoke(invocationInput, request, response);
futureHolder.set(futureResult);
handle(futureResult, request, response, listenerHandler)
.thenAccept(it -> asyncContext.complete());
}); We probably need to introduce something like an |
As this has some security implications I would propose to not set it as default value if possible as a first step? As for the fix: I'm not too deep into the code of |
You'll have to stick with 11.0.0 for now to not have this behavior or just disable It's not running on the same Thread actually. In the snippet above, the |
Yes, I'd just try to mitigate problems for those who update the library and did not notice the change. Otherwise it would make sense to update the Readme so it warns about it. I see, you mean something like this as fix right: spring-projects/spring-security#6856 (comment) ? |
Sorry, wrong button |
Yes exactly. Good point about the readme. I'll add a warning at the top and update the release notes too. |
Shouldn't the executing thread be wrapped in a |
I understand the thought, but |
Is there a way to globally specify the Executor for the AsyncDataFetcher? That way I could specify one that decorates threads with a DelegatingSecurityContext.. val executor = ThreadPoolTaskExecutor()
// Set parallelism explicitly, default is 1
executor.corePoolSize = 5
// Max pool size (threads to scale up to if queue is full)
executor.maxPoolSize = 10
// Possibility to set queue capacity, default is Integer.MAX_VALUE
// executor.setQueueCapacity(500)
executor.setThreadNamePrefix("async-data-fetching-")
executor.setTaskDecorator { runnable -> DelegatingSecurityContextRunnable(runnable) }
executor.initialize()
....
// Pass executor for the AsyncDataFetcher somehow |
That |
Sorry, my example was too specific. It doesn't really matter which executor I pass in, I just wonder if there's a way to specify it myself because then I have the possibility to decide stuff like amount of threads and wrap it in a |
So far I haven't found a way to define the thread pool executor to be used when running |
Propagate the Spring Security context if on the class path. fix #632
@ssprang Got a proof of concept of this working locally:
The proof of concept I have now creates such a public Executor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(asyncServletProperties.getThreads().getMin());
executor.setMaxPoolSize(asyncServletProperties.getThreads().getMax());
executor.setThreadNamePrefix("graphql-");
executor.initialize();
return new DelegatingSecurityContextAsyncTaskExecutor(executor);
} Now I can simply add simple props to be able to configure this async thread pool executor using props and enabling/disabling the security context delegation through props too. Default setting would be that if Spring Security is found on the class path and async mode is enabled it'll configure this for you automatically, assuming you'd want something like this anyway. But with the ability to opt-out. You also raised the idea of being able to provide an |
Propagate the Spring Security context if on the class path. fix #632
Release 12.0.0 will contain support for this. Both through props or even by providing your own graphql:
servlet:
async:
enabled: true
timeout: 30000
delegate-security-context: true
threads:
min: 10 # same default as Tomcat HTTP workers
max: 200 # same default as Tomcat HTTP workers
name-prefix: graphql-exec- |
…sk-decorator fix(#632): propagate spring security context
Very nice! Thank you @oliemansm 🙏🏻 ! This is what I was looking for 😍 |
Really cool thanks a lot! |
Hi!
because
The query looks like
Why is the Authentication only set in the query, but not in the resolvers? |
@PhilippS93 From what I can gather, I don't know if the above is 100% accurate (it's based on a semi-related Stack Overflow answer), but from my own observation, using @oliemansm Do you have any wisdom/comments to offer on the above? EDIT: Based on this tutorial on parallel resolvers, it looks like you can supply the executor as an argument to |
Describe the bug
The Spring Security Context obtained by the OncePerRequestFilter is wrong when upgrading to 11.1.0 with
async-mode-enabled: true
by default.This can lead to very serious security concerns as the context is also not cleared correctly so requests get sometimes authorized with credentials from other users.
To Reproduce
Create a Filter and try to access the context with SecurityContextHolder within the dataFetchers.
Expected behavior
The Security Context should contain the correct context.
The text was updated successfully, but these errors were encountered: