我使用SecurityContextHolder
和自定义UserDetailsService
从UserDetails
获取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),或者可能是完全为空用户。
是否有更好的方法来获取凭据/用户个人资料?
答案 0 :(得分:6)
是的,使用默认策略(MODE_THREADLOCAL
)是线程安全的(只要您不尝试动态更改策略)。但是,如果您希望生成的线程继承父线程的SecurityContext
,则应设置MODE_INHERITABLETHREADLOCAL
。
此外,方面没有任何“线程逻辑”,它们与建议的方法在同一个线程上执行。
答案 1 :(得分:1)
通常,ThreadLocal在全局缓存线程池中不友好。 ExecutorService的默认缓存线程池(Executors.newCachedThreadPool())将具有初始化线程的ThreadLocal存储或空的存储。在这种情况下,设置MODE_INHERITABLETHREADLOCAL将不会更改任何内容,除非每个请求初始化缓存的线程池,这将是一个非常糟糕的用法.. 确保任何底层框架或库没有使用Executors.newCachedThreadPool()来为您提供线程池。
答案 2 :(得分:0)
是的,它是线程安全的。你应该打电话 SecurityContextHolder.getContext()。getAuthentication()。的getName()