2010-02-18 166 views
6

我用SecurityContextHolder和一個自定義UserDetailsServiceSecurityContextHolder獲得UserDetailsSecurityContextHolder線程安全嗎?

Object o = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
UserDetailsDTO user = (UserDetailsDTO) o; 

我離開了null檢查,等等,但是這是想法。我在@Around切入點的@Aspect的使用這樣的:

@Around("execution(* user.service.*.*(..))") 
public Object audit(ProceedingJoinPoint call) throws Throwable { 
    // get user id 
    // add audit row in db 
} 

望着SecurityContextHolder類,它採用了ThreadLocal默認,但在切入點的東西似乎也有某種形式的封裝線程邏輯。

是否有可能存在用戶衝突(即,在另一個併發會話中訪問來自一個會話的UserA審覈事件),或者可能是一個空用戶。

有沒有更好的方法來獲取憑證/用戶配置文件?

回答

5

是的,它的線程安全與默認策略(MODE_THREADLOCAL)(只要你不試圖改變飛行策略)。但是,如果您希望產生的線程繼承父線程的SecurityContext,則應該設置MODE_INHERITABLETHREADLOCAL

其他方面沒有任何「線程邏輯」,它們在與adviced方法相同的線程中執行。

+0

我看到了,但這對於春天的傢伙來說似乎是一個巨大的錯誤。一個靜態的util類,setStrategyName有這個Javadoc blurb:'不要爲給定的JVM多次調用這個方法,因爲它會重新初始化策略,並使用舊的策略對任何現有的線程產生不利影響。'我想我可能會最終創建一個單例包裝類。 – Droo 2010-02-19 01:12:00

+0

我想這裏還有一個系統屬性:'public static final String SYSTEM_PROPERTY =「spring.security.strategy」;' – Droo 2010-02-19 01:53:11

-1

是的,它是線程安全的。你應該只被調用 SecurityContextHolder.getContext()。getAuthentication()的getName()

+0

請原諒downvote請 – vsingh 2017-07-13 15:44:09

1
一般

,ThreadLocal的不會是一個全球性的緩存的線程池友好。 ExecutorService的默認緩存線程池(Executors.newCachedThreadPool())將具有初始化線程的ThreadLocal存儲或空的存儲。在這種情況下,設置MODE_INHERITABLETHREADLOCAL不會改變任何東西,除非緩存線程池被初始化爲每個請求,這將是一個非常糟糕的用法。 確保任何底層框架或庫沒有使用Executors.newCachedThreadPool()來提供線程池爲您服務。