2010-02-18 16 views
6

Io uso SecurityContextHolder e un costume UserDetailsService per ottenere UserDetails da SecurityContextHolder:È sicuro il thread SecurityContextHolder?

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

ho lasciato i controlli nulli, ecc, ma questa è l'idea. Sto usando questo in un @Around pointcut di un @Aspect:

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

Guardando la classe SecurityContextHolder, utilizza una ThreadLocal per impostazione predefinita, ma la roba pointcut sembra anche avere una sorta di logica filettatura incapsulato.

È possibile che si verifichi una collisione tra utenti (ad esempio, accesso a UtenteA da una sessione per un evento di controllo UtenteB in un'altra sessione concorrente) o eventualmente un utente null.

C'è un modo migliore per ottenere le credenziali/profilo utente?

risposta

5

Sì, è thread-safe con la strategia predefinita (MODE_THREADLOCAL) (a condizione che non si tenti di modificare la strategia al volo). Tuttavia, se si desidera che i thread spawn eredino SecurityContext del thread principale, è necessario impostare MODE_INHERITABLETHREADLOCAL.

Anche gli aspetti non hanno alcuna "logica di threading", sono eseguiti nello stesso thread del metodo consigliato.

+0

L'ho visto, ma l'uomo sembra un enorme errore per i ragazzi della Primavera. Una classe util statica e setStrategyName ha questo file Javadoc: 'NON chiamare questo metodo più di una volta per una data JVM, poiché reinizializzerà la strategia e influirà negativamente su qualsiasi thread esistente utilizzando la vecchia strategia. Penso che probabilmente finiscono per creare una classe wrapper singleton. – Droo

+0

Immagino ci sia anche una proprietà di sistema: 'public static final String SYSTEM_PROPERTY =" spring.security.strategy ";' – Droo

-1

Sì, è sicuro da thread. Dovresti solo chiamare SecurityContextHolder.getContext(). GetAuthentication(). GetName()

+0

Motivi per downvota per favore – vsingh

1

in generale, ThreadLocal non sarà amichevole in un pool di thread memorizzato nella cache globale. Un pool di thread memorizzato nella cache di ExecutorService (Executors.newCachedThreadPool()) avrà o l'archiviazione ThreadLocal del thread di inizializzazione o vuota. In questa situazione, l'impostazione di MODE_INHERITABLETHREADLOCAL non cambierà nulla, a meno che il threadpool memorizzato nella cache non sia inizializzato per richiesta, il che sarebbe un utilizzo piuttosto cattivo. Assicurarsi che i framework o le librerie sottostanti non stiano utilizzando Executors.newCachedThreadPool() per fornire pooling di thread per te.