SecurityContextHolder线程安全吗?

时间:2010-02-18 20:25:14

标签: java spring spring-mvc spring-security

我使用SecurityContextHolder和自定义UserDetailsServiceUserDetails获取SecurityContextHolder

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

我遗漏了空检查等,但这就是主意。我在@Around的{​​{1}}切入点中使用它:

@Aspect

查看@Around("execution(* user.service.*.*(..))") public Object audit(ProceedingJoinPoint call) throws Throwable { // get user id // add audit row in db } 类,它默认使用SecurityContextHolder,但切入点的东西似乎也有某种封装的线程逻辑。

是否可能存在用户冲突(即,在一个会话中为另一个并发会话中的UserB审核事件访问UserA),或者可能是完全为空用户。

是否有更好的方法来获取凭据/用户个人资料?

3 个答案:

答案 0 :(得分:6)

是的,使用默认策略(MODE_THREADLOCAL)是线程安全的(只要您不尝试动态更改策略)。但是,如果您希望生成的线程继承父线程的SecurityContext,则应设置MODE_INHERITABLETHREADLOCAL

此外,方面没有任何“线程逻辑”,它们与建议的方法在同一个线程上执行。

答案 1 :(得分:1)

通常,ThreadLocal在全局缓存线程池中不友好。 ExecutorService的默认缓存线程池(Executors.newCachedThreadPool())将具有初始化线程的ThreadLocal存储或空的存储。在这种情况下,设置MODE_INHERITABLETHREADLOCAL将不会更改任何内容,除非每个请求初始化缓存的线程池,这将是一个非常糟糕的用法.. 确保任何底层框架或库没有使用Executors.newCachedThreadPool()来为您提供线程池。

答案 2 :(得分:0)

是的,它是线程安全的。你应该打电话 SecurityContextHolder.getContext()。getAuthentication()。的getName()