-
Notifications
You must be signed in to change notification settings - Fork 191
SecurityContextHolder is not propagated into @Transactional methods #1944
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The default strategy for SecurityContextHolder is MODE_THREADLOCAL. The spring-data-implemenation of @transactional does not execute the method in the same thread as it was called from. Using MODE_GLOBAL will allow it to be retrieved from a different thread, but is not suitable for multi-user, multi-threaded applications. I would suggested retrieving the authorization in the caller and passing it as an argument to the service.
|
hi @mikereiche
This is clear and this is one of the reasons why we're using MODE_INHERITABLETHREADLOCAL. Is there any reason not to pass security context if we're using |
Applications typically have a single uber Context object that holds multiple objects and is passed as an argument to methods that need the context. As additional objects are needed, they are just added to the Context object, there is no need to add arguments. Passing as an argument also avoids any future problems where SomeFutureContextHolder will not work.
There is no reason not to pass it. It's just that thread-local mechanisms of SecureContextHolder don't work. SecureContextHolder does have means for you to provide a custom strategy. Because @transactional uses reactor, it executes the method in a thread from The mechanism for passing contextual data through a reactive chain is by writing it to the reactive context using contextWrite(). However - the call to a @transactional method is simply a method call - nothing from implementation is exposed, so there is no place to do that contextWrite() from the caller. Furthermore, the Couchbase Transaction call ReactiveTransaction.runBlocking(...) does not expose the context either. Even if a ReactiveTransaction.runBlockingWriteContext(...., ctx) was added, the caller would need to know what to what 'ctx' was. It could possibly be something analogous to SecurityContextHolder - such as TransactionContextHolder that uses ThreadLocal. ThreadLocal would work for this since it would be stored and retrieved in the same thread - before the execution of the reactor chain. |
we're using org.springframework.security.core.context.SecurityContextHolder#MODE_INHERITABLETHREADLOCAL . In such case - even if thread will not be the same thread as before - context should be passed to newly created thread from current one, isn't it? see https://docs.spring.io/spring-security/site/docs/3.0.x/reference/technical-overview.html. So, the question - why it's not working for MODE_INHERITABLETHREADLOCAL and will it be fixed? |
That is correct, but it's not the case here. Please refer to my previous post where I provided all the details and all the options.
You can file a ticket with spring-boot security for SecurityContextHolder, and they will tell you the same thing. |
I have stumbled on the same problem: when using It's pretty sad and a major problem for me. I don't even know what to do now, I have used MongoDB (with Spring Data Mongo), and it was working with the same code perfectly. I hoped to try Couchbase....
It's so sad in its current state Couchbase with spring-data plus transactions looks unusable. |
Neither. The problem is that SecurityContextHolder does not provide a mode to propagate through a Reactor context. |
investigating what can be done. |
@Burtsev-Alexey @leonidr82 - there is support in 5.4.0-SNAPSHOT and 5.3.5-SNAPSHOT There is info here on how to use the snapshots - https://docs.spring.io/spring-data/couchbase/reference/couchbase/configuration.html#snapshot-configuration |
We have next state: One of the services (say ResolverService service) calling another service (say SpaceService service). Resolver service invoking method resolverA method with call to some api (say spaceA) from Space service.
At scope of resolverA we have Security context - e.g.
SecurityContextHolder.getContext().getAuthentication()
holds relevant jwt authentication object.When we going inside of SpaceService#spaceA - Security context has been nullified (e.g.
SecurityContextHolder.getContext().getAuthentication()
returns null).while in given case i would expect to get this context.
If
@Transactional
attribute removed from SpaceService class - Security context presented and passed as it should.Security context should be passed correctly if @Transacitonal attribute in use.
The text was updated successfully, but these errors were encountered: