2012-02-15 3 views
5

Avere semplice webapp Primavera di sicurezza con la codifica passwordAutenticazione in Primavera di sicurezza whith password di codifica

<security:authentication-manager alias="authenticationManager"> 
<security:authentication-provider user-service-ref="personService"> 
    <security:password-encoder hash="md5" ref="passwordEncoder"> 
     <!-- <security:salt-source user-property="username"/> --> 
    </security:password-encoder> 
</security:authentication-provider> 
</security:authentication-manager> 

codifica anche semplice:

person.setPassword(encoder.encodePassword(person.getPassword(), null)); 

Così nel database verrà codificato tutte le password. Ora voglio eseguire l'autenticazione di alcuni utenti con un determinato nome utente all'interno dell'applicazione. Prima (quando passswords era in chiaro) è stato come questo:

UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
       username, password); 
Authentication authentication = authenticationManager.authenticate(token); 
SecurityContextHolder.getContext().setAuthentication(authentication); 

Ma ora ho codificato password dal DB e non posso fare l'autenticazione come prima.

Il problema. che Spring non sappia che la password proviene da UsernamePasswordAuthenticationToken già codificata. E lo sta codificando per la seconda volta. Chi può aiutare?

Modifica

Così vedo due soluzioni qui:

  1. implementano DaoAuthenticationProvider personalizzata in cui aggiungere controllo se entrambe le password hash già
  2. implementare l'autenticazione personalizzati e metterlo nel contesto di protezione manualmente.

Altri? Qual è la migliore?

+0

comprende alcuni dei SpringSecurity in [dettaglio qui] (http://techastute.blogspot.com /2013/01/spring-security-in-detail.html), potrebbe essere utile per qualcuno. – raksja

risposta

7

Non hai effettivamente detto cosa va storto, ma il codice di autenticazione dovrebbe essere esattamente lo stesso della versione non hash.

Se nel database è presente una password con hash e l'encoder corrispondente immesso nel provider di autenticazione, la password fornita dall'utente verrà sottoposta a hashing dal codificatore prima di confrontarla con la versione del database.

verificare che:

  1. si utilizza il valore della password unhashed durante la creazione del UsernamePasswordAuthenticationToken
  2. Il valore nel database è davvero lo stesso del hash prodotta dal codificatore. Caricalo tu stesso e controllalo in un test. Il database potrebbe essere memorizzato in maiuscolo, per esempio.

Inoltre, probabilmente dovresti scegliere qualcosa di meglio del semplice MD5. Ad esempio, potresti voler vedere bcrypt, che è supportato in Spring Security 3.1 e utilizza automaticamente un valore salt random.

Aggiornamento

Il tuo suggerimento di creare un fornitore che accetta le password hash non è un buon compromesso. Ciò consentirebbe a chiunque rubi un hash della password di autenticarsi direttamente con esso (sconfiggendo in tal modo lo scopo dell'hashing in primo luogo).

Basta convalidare la tua email collegamenti URL, caricare le informazioni per l'utente e creare un oggetto Authentication per loro:

UserDetails user = ... // load user here 
Authentication a = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); 
SecurityContextHolder.getContext().setAuthentication(a); 
+0

Il problema è in 1. Durante la creazione di UsernamePasswordAuthenticationToken ho solo una versione hash della password mentre carico l'oggetto UserDetails da DB (nel mio caso - tramite chiave di conferma) – vacuum

+0

L'uso della password memorizzata non autentica l'utente (che presumo sia cosa stai cercando di fare). In caso contrario, dovrai chiarire cosa stai cercando di ottenere. Non ha molto senso chiamare il gestore autenticazione con una password che sai essere corretta in anticipo. –

+0

Sto tentando di autenticare l'utente, che ha fatto clic su un link dall'email di registrazione. Quindi l'oggetto UserDetails proviene dal DB con la chiave di conferma che proviene dal link di conferma nell'email. – vacuum