Codificatore password predefinito in Spring Security 5

1. Panoramica

In Spring Security 4, era possibile memorizzare le password in testo normale utilizzando l'autenticazione in memoria.

Una profonda revisione del processo di gestione delle password nella versione 5 ha introdotto un meccanismo predefinito più sicuro per la codifica e la decodifica delle password. Ciò significa che se l'applicazione Spring memorizza le password in testo normale, l'aggiornamento a Spring Security 5 può causare problemi.

In questo breve tutorial, descriveremo uno di quei potenziali problemi e dimostreremo una soluzione.

2. Spring Security 4

Inizieremo mostrando una configurazione di sicurezza standard che fornisce una semplice autenticazione in memoria (valida per Spring 4):

@Configuration public class InMemoryAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("spring") .password("secret") .roles("USER"); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/private/**") .authenticated() .antMatchers("/public/**") .permitAll() .and() .httpBasic(); } } 

Questa configurazione definisce l'autenticazione per tutti i metodi / private / mappati e l'accesso pubblico per tutto ciò che è in / public /.

Se usiamo la stessa configurazione in Spring Security 5, otterremo il seguente errore:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

L'errore ci dice che la password fornita non può essere decodificata poiché nessun codificatore di password è stato configurato per la nostra autenticazione in memoria .

3. Spring Security 5

Possiamo correggere questo errore definendo un Delegating PasswordEncoder con la classe PasswordEncoderFactories .

Usiamo questo codificatore per configurare il nostro utente con AuthenticationManagerBuilder:

@Configuration public class InMemoryAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); auth.inMemoryAuthentication() .withUser("spring") .password(encoder.encode("secret")) .roles("USER"); } } 

Ora, con questa configurazione, stiamo archiviando la nostra password in memoria utilizzando BCrypt nel seguente formato:

{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS 

Sebbene possiamo definire il nostro set di codificatori di password, si consiglia di attenersi ai codificatori predefiniti forniti in PasswordEncoderFactories .

3.2. NoOpPasswordEncoder

Se, per qualsiasi motivo, non vogliamo codificare la password configurata, possiamo utilizzare il NoOpPasswordEncoder .

Per fare ciò, anteponiamo semplicemente alla passphrase che forniamo al metodo password () l' identificatore {noop} :

@Configuration public class InMemoryNoOpAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("spring") .password("{noop}secret") .roles("USER"); } } 

In questo modo, Spring Security utilizzerà NoOpPasswordEncoder sotto il cofano quando confronta la password fornita dall'utente con quella che abbiamo configurato sopra.

Si noti, tuttavia, che non dovremmo mai utilizzare questo approccio sull'applicazione di produzione! Come dice la documentazione ufficiale, NoOpPasswordEncoder è stato deprecato per indicare che si tratta di un'implementazione legacy e il suo utilizzo è considerato non sicuro .

3.3. Migrazione delle password esistenti

Possiamo aggiornare le password esistenti agli standard consigliati di Spring Security 5:

  • Aggiornamento delle password archiviate in testo normale con il loro valore codificato:
String encoded = new BCryptPasswordEncoder().encode(plainTextPassword); 
  • Prefisso delle password memorizzate con hash con il loro identificatore codificatore noto:
{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS {sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0 
  • Richiesta agli utenti di aggiornare le proprie password quando il meccanismo di codifica per le password memorizzate è sconosciuto

4. Conclusione

In questo rapido esempio, abbiamo aggiornato una configurazione di autenticazione in memoria Spring 4 valida alla Spring 5 utilizzando il nuovo meccanismo di archiviazione delle password.

Come sempre, puoi trovare il codice sorgente sul progetto GitHub.