Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is SecurityContextHolder thread safe?

I use SecurityContextHolder and a custom UserDetailsService to obtain UserDetails from SecurityContextHolder:

Object o = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetailsDTO user = (UserDetailsDTO) o;

I left out the null checks, etc., but that's the idea. I'm using this in an @Around pointcut of an @Aspect:

@Around("execution(* user.service.*.*(..))")
public Object audit(ProceedingJoinPoint call) throws Throwable {
     // get user id
     // add audit row in db
}

Looking at the SecurityContextHolder class, it uses a ThreadLocal by default, but the pointcut stuff also seems to have some sort of encapsulated threading logic.

Is it possible that there could be user collision (i.e. access UserA from one session for a UserB audit event in another concurrent session), or possibly a null user altogether.

Is there a better way to obtain the credentials/user profile?

like image 961
Droo Avatar asked Feb 18 '10 20:02

Droo


People also ask

What is the use of SecurityContextHolder?

The SecurityContextHolder is a helper class, which provide access to the security context. By default, it uses a ThreadLocal object to store security context, which means that the security context is always available to methods in the same thread of execution, even if you don't pass the SecurityContext object around.

How does SecurityContextHolder getContext () work?

By default the SecurityContextHolder uses a ThreadLocal to store these details, which means that the SecurityContext is always available to methods in the same thread, even if the SecurityContext is not explicitly passed around as an argument to those methods.

What is SecurityContextHolder getContext () getAuthentication ()?

The HttpServletRequest.getUserPrincipal() will return the result of SecurityContextHolder.getContext().getAuthentication() . This means it is an Authentication which is typically an instance of UsernamePasswordAuthenticationToken when using username and password based authentication.

What is spring SecurityContext?

The SecurityContext is used to store the details of the currently authenticated user, also known as a principle. So, if you have to get the username or any other user details, you need to get this SecurityContext first. The SecurityContextHolder is a helper class, which provides access to the security context.


2 Answers

Yes, it's thread safe with the default strategy (MODE_THREADLOCAL) (as long as you don't try to change the strategy on the fly). However, if you want spawned threads to inherit SecurityContext of the parent thread, you should set MODE_INHERITABLETHREADLOCAL.

Also aspects don't have any "threading logic", they are executed at the same thread as the adviced method.

like image 130
axtavt Avatar answered Oct 05 '22 23:10

axtavt


in general, ThreadLocal will not be friendly in a global cached thread pool. An ExecutorService's default cached thread pool (Executors.newCachedThreadPool()) will have either the initializing thread's ThreadLocal storage, or an empty one. In this situation, setting MODE_INHERITABLETHREADLOCAL will not change anything, unless the cached threadpool is initialized per request, which would be a pretty bad usage of it.. Make sure any underlying frameworks or libraries are not using the Executors.newCachedThreadPool() to provide thread pooling for you.

like image 28
bmadigan Avatar answered Oct 05 '22 23:10

bmadigan