方案:
- 在任务提交时将SecurityContext信息传递给线程池:在主线程中,以及每次向线程池提交任务时,将当前的SecurityContext信息传递给任务。在子线程中,通过获取传递的SecurityContext信息来使用SecurityContextHolder获取用户信息。
代码
public class SecurityContextAwareRunnable implements Runnable {
private final Runnable task;
private final SecurityContext securityContext;
public SecurityContextAwareRunnable(Runnable task, SecurityContext securityContext) {
this.task = task;
this.securityContext = securityContext;
}
@Override
public void run() {
SecurityContextHolder.setContext(securityContext);
try {
task.run();
} finally {
SecurityContextHolder.clearContext();
}
}
}
// 创建主线程时,获取当前的SecurityContext
SecurityContext securityContext = SecurityContextHolder.getContext();
// 创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
// 提交任务时,使用SecurityContextAwareRunnable来包装任务,并传递SecurityContext信息
executorService.submit(new SecurityContextAwareRunnable(() -> {
// 在子线程中使用SecurityContextHolder获取用户信息
SecurityContext context = SecurityContextHolder.getContext();
// 然后可以通过context获取用户信息,如:context.getAuthentication().getPrincipal()
}, securityContext));