Standaard wachtwoord-encoder in Spring Security 5

1. Overzicht

In Spring Security 4 was het mogelijk om wachtwoorden op te slaan in platte tekst met behulp van in-memory authenticatie.

Een ingrijpende herziening van het wachtwoordbeheerproces in versie 5 heeft een veiliger standaardmechanisme geïntroduceerd voor het coderen en decoderen van wachtwoorden. Dit betekent dat als uw Spring-applicatie wachtwoorden in platte tekst opslaat, het upgraden naar Spring Security 5 problemen kan veroorzaken.

In deze korte tutorial beschrijven we een van die mogelijke problemen en demonstreren we een oplossing.

2. Veerbeveiliging 4

We beginnen met het tonen van een standaardbeveiligingsconfiguratie die eenvoudige authenticatie in het geheugen biedt (geldig voor Spring 4):

@Configuration openbare klasse InMemoryAuthWebSecurityConfigurer breidt WebSecurityConfigurerAdapter uit {@Override protected void configure (AuthenticationManagerBuilder auth) genereert Uitzondering {auth.inMemoryAuthentication () .withUser ("spring") .password ("secret") .roles ("USER") .roles ("USER"). } @Override protected void configure (HttpSecurity http) genereert uitzondering {http.authorizeRequests () .antMatchers ("/ private / **") .authenticated () .antMatchers ("/ public / **") .permitAll () .en () .httpBasic (); }} 

Deze configuratie definieert authenticatie voor iedereen /privaat/ in kaart gebrachte methoden en openbare toegang voor alles onder /openbaar/.

Als we dezelfde configuratie gebruiken onder Spring Security 5, krijgen we de volgende foutmelding:

java.lang.IllegalArgumentException: Er is geen PasswordEncoder toegewezen aan de id "null"

De fout vertelt ons dat het opgegeven wachtwoord kon niet worden gedecodeerd omdat er geen wachtwoord-encoder is geconfigureerd voor onze in-memory authenticatie.

3. Veerbeveiliging 5

We kunnen deze fout oplossen door een DelegerenWachtwoord Encoder met de WachtwoordEncoderFactories klasse.

We gebruiken deze encoder om onze gebruiker te configureren met de AuthenticationManagerBuilder:

@Configuration openbare klasse InMemoryAuthWebSecurityConfigurer breidt WebSecurityConfigurerAdapter uit {@Override protected void configure (AuthenticationManagerBuilder auth) gooit uitzondering {PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder (); auth.inMemoryAuthentication () .withUser ("spring") .password (encoder.encode ("secret")) .roles ("USER"); }} 

Nu, met deze configuratie, slaan we ons in-memory wachtwoord op met behulp van BCrypt in het volgende formaat:

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

Hoewel we onze eigen set wachtwoord-encoders kunnen definiëren, is het raadzaam om vast te houden aan de standaard encoders die in WachtwoordEncoderFactories.

3.2. NoOpPasswordEncoder

Als we om wat voor reden dan ook het geconfigureerde wachtwoord niet willen coderen, kunnen we gebruik maken van het NoOpPasswordEncoder.

Om dit te doen, voegen we de wachtwoordzin die we verstrekken simpelweg toe aan het wachtwoord() methode met de {noop} identificatie:

@Configuration openbare klasse InMemoryNoOpAuthWebSecurityConfigurer breidt WebSecurityConfigurerAdapter {@Override protected void configure (AuthenticationManagerBuilder auth) uit Exception {auth.inMemoryAuthentication () .withUser ("spring") .password (") {nroloopes;} (secret" USER ");} }} 

Op deze manier gebruikt Spring Security de NoOpPasswordEncoder onder de motorkap wanneer het het wachtwoord van de gebruiker vergelijkt met het wachtwoord dat we hierboven hebben geconfigureerd.

Let echter op dat we deze benadering nooit mogen gebruiken op de productietoepassing! Zoals de officiële documentatie zegt, is het NoOpPasswordEncoder is verouderd om aan te geven dat het een verouderde implementatie is en dat het gebruik ervan als onveilig wordt beschouwd.

3.3. Bestaande wachtwoorden migreren

We kunnen bestaande wachtwoorden bijwerken naar de aanbevolen Spring Security 5-normen door:

  • Opgeslagen wachtwoorden in platte tekst bijwerken met hun gecodeerde waarde:
String gecodeerd = nieuwe BCryptPasswordEncoder (). Encode (plainTextPassword); 
  • Voorvoegsel van gehashte opgeslagen wachtwoorden met hun bekende encoder-ID:
{bcrypt} $ 2a $ 10 $ MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS {sha256} 97cde38028ad898ebc02e690819fa220e88c62e0699403ef94fff542e0699401effff5f9cbf9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9fbff9cbf9cbff9cbff9fbff9fbff9fbfff9fbffbff9fbff9fbff9fbff9fbfbff9fbff9cbffff9fbfffbff9fbfffbffbc62e0699403efdfffffbc62e0699403efbffffbc690819fa220e88c62e0699403efffff 
  • Gebruikers vragen hun wachtwoorden bij te werken wanneer het coderingsmechanisme voor opgeslagen wachtwoorden onbekend is

4. Conclusie

In dit korte voorbeeld hebben we een geldige Spring 4-in-memory authentication-configuratie bijgewerkt naar Spring 5 met behulp van het nieuwe wachtwoordopslagmechanisme.

Zoals altijd kun je de broncode vinden op het GitHub-project.