2017-02-20 141 views
1

您好,我有一些问题,当在线程范围内使用Spring Security春季安全当前用户线程

System.out.println(((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId()); 
new Thread(() -> System.out.println(((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId())).start(); 

这两条线应该给我当前用户ID

第一线工作的预期

第二行给我NullPointerException,因为没有当前用户它是空值

我发现这个问题,因为我想保存许多行到t他歌曲表和它hava @CreatedBy用户,这将要求当前用户在线程和将失败,因为这将给当前用户空值

+1

你为什么想为得到一个单独的线程当前用户?按照第一个选项中的建议操作。 –

+0

默认情况下,Spring Security的'Authentication'对象存储在一个'ThreadLocal'在每个'Thread'基础。因此,用'new Thread'激发一个新线程,然后试图在新线程内检索'Authentication'对象将返回'null'。官方的Spring Security文档提供了[多个选项](http://docs.spring.io/spring-security/site/docs/current/reference/html/concurrency.html)在多线程环境中工作。查看文档并选择适合您的环境的策略。 – manish

+1

你为什么要拥有独立的线程获取当前用户¿因为我不是要求获得当前用户的createdby注释调用它,它调用它,我已创建所以这做弹簧魔法线程 –

回答

2

如果你想产生的线程继承父线程的SecurityContext,你应该设置MODE_INHERITABLETHREADLOCAL策略。

请参阅SecurityContextHolder API。

参考this

2

,你可以从一个线程转移SecurityContext的另一个

Runnable originalRunnable = new Runnable() { 
public void run() { 
    // invoke secured service 
} 
}; 
SecurityContext context = SecurityContextHolder.getContext(); 
DelegatingSecurityContextRunnable wrappedRunnable = 
    new DelegatingSecurityContextRunnable(originalRunnable, context); 

new Thread(wrappedRunnable).start(); 

见并发支持

http://docs.spring.io/spring-security/site/docs/current/reference/html/concurrency.html