2017-02-20 136 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