Nouveau stockage du mot de passe dans Spring Security 5

Nouveau stockage de mots de passe dans Spring Security 5

1. introduction

Avec la dernière version de Spring Security, beaucoup de choses ont changé. L'un de ces changements concerne la manière dont nous pouvons gérer le codage des mots de passe dans nos applications.

Dans ce didacticiel, nous allons explorer certains de ces changements.

Plus tard, nous verrons comment configurer le nouveau mécanisme de délégation et comment mettre à jour notre codage de mot de passe existant, sans que nos utilisateurs ne le reconnaissent.

2. Changements pertinents dans Spring Security 5.x

L'équipe Spring Security a déclaré lesPasswordEncoder dansorg.springframework.security.authentication.encoding comme obsolètes. C'était une décision logique, car l'ancienne interface n'était pas conçue pour un sel généré de manière aléatoire. Par conséquent, la version 5 a supprimé cette interface.

En outre, Spring Security modifie la façon dont il traite les mots de passe codés. Dans les versions précédentes, chaque application utilisait un seul algorithme de codage de mot de passe.

Par défaut,StandardPasswordEncoder s'en occupe. Il a utilisé SHA-256 pour l'encodage. En changeant l'encodeur de mot de passe, nous pourrions passer à un autre algorithme. Mais notre application devait respecter exactement un algorithme.

Version 5.0 introduces the concept of password encoding delegation. Maintenant, nous pouvons utiliser différents encodages pour différents mots de passe. Spring reconnaît l'algorithme par un identifiant préfixant le mot de passe codé.

Voici un exemple de mot de passe codé bcrypt:

{bcrypt}$2b$12$FaLabMRystU4MLAasNOKb.HUElBAabuQdX59RWHq5X.9Ghm692NEi

Notez comment bcrypt est spécifié entre accolades au tout début.

3. Configuration de la délégation

If the password hash has no prefix, the delegation process uses a default encoder. Ainsi, par défaut, nous obtenons lesStandardPasswordEncoder.

Cela le rend compatible avec la configuration par défaut des versions précédentes de Spring Security.

Avec la version 5, Spring Security introduitPasswordEncoderFactories.createDelegatingPasswordEncoder(). Cette méthode d'usine renvoie une instance configurée deDelegationPasswordEncoder.

Pour les mots de passe sans préfixe, cette instance garantit le comportement par défaut susmentionné. Et pour les hachages de mots de passe contenant un préfixe, la délégation est effectuée en conséquence.

L'équipe Spring Security répertorie les algorithmes pris en charge dans la dernière version decorresponding JavaDoc.

Bien entendu, Spring nous permet de configurer ce comportement.

Supposons que nous souhaitons soutenir:

  • bcrypt comme nouvelle valeur par défaut

  • scrypt comme alternative

  • SHA-256 comme algorithme actuellement utilisé.

La configuration de cette configuration ressemblera à ceci:

@Bean
public PasswordEncoder delegatingPasswordEncoder() {
    PasswordEncoder defaultEncoder = new StandardPasswordEncoder();
    Map encoders = new HashMap<>();
    encoders.put("bcrypt", new BCryptPasswordEncoder());
    encoders.put("scrypt", new SCryptPasswordEncoder());

    DelegatingPasswordEncoder passworEncoder = new DelegatingPasswordEncoder(
      "bcrypt", encoders);
    passworEncoder.setDefaultPasswordEncoderForMatches(defaultEncoder);

    return passworEncoder;
}

4. Migration de l'algorithme de codage de mot de passe

Dans la section précédente, nous avons exploré comment configurer le codage de mot de passe en fonction de nos besoins. Therefore, now we’ll work on how to switch an already encoded password to a new algorithm.

Imaginons que nous voulions changer le codage deSHA-256 àbcrypt, mais nous ne voulons pas que nos utilisateurs modifient leurs mots de passe.

Une solution possible consiste à utiliser la demande de connexion. À ce stade, nous pouvons accéder aux informations d'identification en texte brut. C'est le moment où nous pouvons prendre le mot de passe actuel et le ré-encoder.

Par conséquent, nous pouvons utiliser lesAuthenticationSuccessEvent de Spring pour cela. Cet événement se déclenche après qu'un utilisateur s'est connecté avec succès à notre application.

Voici l'exemple de code:

@Bean
public ApplicationListener
  authenticationSuccessListener( PasswordEncoder encoder) {
    return (AuthenticationSuccessEvent event) -> {
        Authentication auth = event.getAuthentication();

        if (auth instanceof UsernamePasswordAuthenticationToken
          && auth.getCredentials() != null) {

            CharSequence clearTextPass = (CharSequence) auth.getCredentials();
            String newPasswordHash = encoder.encode(clearTextPass);

            // [...] Update user's password

            ((UsernamePasswordAuthenticationToken) auth).eraseCredentials();
        }
    };
}

Dans l'extrait précédent:

  • Nous avons récupéré le mot de passe de l'utilisateur en texte clair à partir des détails d'authentification fournis

  • Création d'un nouveau hachage de mot de passe avec le nouvel algorithme

  • Suppression du mot de passe en texte clair du jeton d'authentification

Par défaut, l'extraction du mot de passe en texte clair ne serait pas possible car Spring Security le supprime dès que possible.

Par conséquent, nous devons configurer Spring pour qu'il conserve la version en clair du mot de passe.

De plus, nous devons enregistrer notre délégation de codage:

@Configuration
public class PasswordStorageWebSecurityConfigurer
  extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
      throws Exception {
        auth.eraseCredentials(false)
          .passwordEncoder(delegatingPasswordEncoder());
    }

    // ...
}

5. Conclusion

Dans cet article rapide, nous avons parlé de nouvelles fonctionnalités d'encodage des mots de passe disponibles dans la version 5.x.

Nous avons également vu comment configurer plusieurs algorithmes de codage de mots de passe pour coder nos mots de passe. De plus, nous avons exploré un moyen de changer le codage du mot de passe, sans casser le codage existant.

Enfin, nous avons décrit comment utiliser les événements Spring pour mettre à jour le mot de passe utilisateur chiffré de manière transparente, ce qui nous permet de modifier de manière transparente notre stratégie de codage sans le divulguer à nos utilisateurs.

Enfin et comme toujours, tous les exemples de code sont disponibles dans nosGitHub repository.