Codeur de mot de passe par défaut dans Spring Security 5

Codeur de mot de passe par défaut dans Spring Security 5

1. Vue d'ensemble

Dans Spring Security 4, il était possible de stocker les mots de passe en texte brut à l'aide de l'authentification en mémoire.

Une refonte majeure du processus de gestion des mots de passe dans la version 5 a introduit un mécanisme par défaut plus sécurisé pour le codage et le décodage des mots de passe. Cela signifie que si votre application Spring stocke les mots de passe en texte brut, la mise à niveau vers Spring Security 5 peut poser des problèmes.

Dans ce court didacticiel, nous décrirons l'un de ces problèmes potentiels et vous montrerons une solution à ce problème.

2. Spring Security 4

Nous allons commencer par montrer une configuration de sécurité standard qui fournit une authentification en mémoire simple (valable pour 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();
    }
}

Cette configuration définit l'authentification pour toutes les méthodes mappées/private/ et l'accès public pour tout ce qui est sous/public/.

Si nous utilisons la même configuration sous Spring Security 5, nous obtiendrons l'erreur suivante:

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

L'erreur nous indique que le mot de passe donnécouldn’t be decoded since no password encoder was configured for our in-memory authentication.

3. Sécurité de printemps 5

Nous pouvons corriger cette erreur en définissant un commutateurDelegatingPasswordEncoder avec la classePasswordEncoderFactories.

Nous utilisons cet encodeur pour configurer notre utilisateur avec lesAuthenticationManagerBuilder:

@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");
    }
}

Désormais, avec cette configuration, nous stockons notre mot de passe en mémoire à l'aide de BCrypt au format suivant:

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

Bien que nous puissions définir notre propre ensemble d'encodeurs de mots de passe, il est recommandé de s'en tenir auxdefault encoders fournis dansPasswordEncoderFactories.

3.1. Migration des mots de passe existants

Nous pouvons mettre à jour les mots de passe existants conformément aux normes Spring Security 5 recommandées en:

  • Mise à jour des mots de passe stockés en texte brut avec leur valeur codée:

String encoded = new BCryptPasswordEncoder().encode(plainTextPassword);
  • Préfixe des mots de passe stockés hachés avec leur identificateur de codeur connu:

{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
  • Demander aux utilisateurs de mettre à jour leurs mots de passe lorsque le mécanisme de codage des mots de passe stockés est inconnu

4. Conclusion

Dans cet exemple rapide, nous avons mis à jour une configuration d'authentification en mémoire Spring 4 valide vers Spring 5 à l'aide du nouveau mécanisme de stockage du mot de passe.

Comme toujours, vous pouvez trouver le code source sur lesGitHub project.