views:

498

answers:

1

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?

+1  A: 

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.

axtavt
I saw that, but man does that seem like a huge miscue for the Spring guys. A static util class, and setStrategyName has this Javadoc blurb: `Do NOT call this method more than once for a given JVM, as it will reinitialize the strategy and adversely affect any existing threads using the old strategy.` I think I'll probably end up creating a singleton wrapper class.
Droo
I guess there is also a system property: `public static final String SYSTEM_PROPERTY = "spring.security.strategy";`
Droo