spring security获取用户信息为null或者串值

 在spring security,用SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取登录用户的信息,发现获取到的用户有串值现象——获取用户信息,发现获取到的是别人的信息,偶发性还有取值为null的情况。经同事提醒,是不是用了多线程,查到了问题的原因。

//原代码
ExecutorService executorService = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("job").build());
 
executorService.execute(() -> {
       //获取用户对象
       LoginUserDetails userDetails = (LoginUserDetails)SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        
});

//改进后
ExecutorService executorService = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("job").build());

SecurityContext securityContext = SecurityContextHolder.getContext();
 
executorService.execute(() -> {
       //把context设置进去
       SecurityContextHolder.setContext(securityContext);
       //获取用户对象
       LoginUserDetails userDetails = (LoginUserDetails)SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        
});

源码:

ThreadLocal是线程独有的局部变量,只针对当前线程,当前代码里使用了嵌套线程,子线程里的SecurityContext和父线程里的SecurityContext不是同一个,需要从父线程把SecurityContext传入到子线程