Enregistrement avec Spring Security - Encodage du mot de passe

Enregistrement avec Spring Security - Encodage du mot de passe

1. Vue d'ensemble

Cet article traite d'une partie critique du processus d'enregistrement -password encoding - ne stockant essentiellement pas le mot de passe en texte brut.

Il existe quelques mécanismes d'encodage pris en charge par Spring Security - et pour l'articlewe’ll use BCrypt, car c'est généralement la meilleure solution disponible.

La plupart des autres mécanismes, tels que lesMD5PasswordEncoder etShaPasswordEncoder utilisent des algorithmes plus faibles et sont désormais obsolètes.

Lectures complémentaires:

Nouveau stockage de mots de passe dans Spring Security 5

Un guide rapide pour comprendre le chiffrement de mot de passe dans Spring Security 5 et migrer vers de meilleurs algorithmes de chiffrement.

Read more

Autoriser l'authentification à partir des emplacements acceptés uniquement avec Spring Security

Découvrez comment autoriser les utilisateurs à s'authentifier à partir d'emplacements acceptés uniquement avec Spring Security.

Read more

Spring Security - Utilisateur avec connexion automatique après l'enregistrement

Apprenez à authentifier rapidement un utilisateur une fois le processus d'enregistrement terminé.

Read more

2. Définir le codeur de mot de passe

Nous allons commencer par définir le simple BCryptPasswordEncoder comme un bean dans notre configuration:

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

Les implémentations plus anciennes - telles queSHAPasswordEncoder - nécessiteraient que le client transmette une valeur salt lors du codage du mot de passe.

BCrypt, cependant,will internally generate a random salt à la place. Ceci est important à comprendre car cela signifie que chaque appel aura un résultat différent, nous devons donc encoder le mot de passe une seule fois.

Sachez également que l'algorithmeBCrypt génère une chaîne de longueur 60, nous devons donc nous assurer que le mot de passe sera stocké dans une colonne qui peut l'accueillir. Une erreur courante est de créer une colonne d'une longueur différente, puis d'obtenir une erreurInvalid Username or Password au moment de l'authentification.

3. Encoder le mot de passe lors de l'inscription

Nous allons maintenant utiliser lesPasswordEncoder dans nosUserService pour hacher le mot de passe pendant le processus d'enregistrement de l'utilisateur:

Exemple 3.1. - LeUserService hache le mot de passe

@Autowired
private PasswordEncoder passwordEncoder;

@Override
public User registerNewUserAccount(UserDto accountDto) throws EmailExistsException {
    if (emailExist(accountDto.getEmail())) {
        throw new EmailExistsException(
          "There is an account with that email adress:" + accountDto.getEmail());
    }
    User user = new User();
    user.setFirstName(accountDto.getFirstName());
    user.setLastName(accountDto.getLastName());

    user.setPassword(passwordEncoder.encode(accountDto.getPassword()));

    user.setEmail(accountDto.getEmail());
    user.setRole(new Role(Integer.valueOf(1), user));
    return repository.save(user);
}

4. Encoder le mot de passe lors de l'authentification

Nous allons maintenant gérer l'autre moitié de ce processus et encoder le mot de passe lorsque l'utilisateur s'authentifie.

Premièrement, nous devons injecter le bean encodeur de mot de passe que nous avons défini précédemment dans notre fournisseur d'authentification:

@Autowired
private UserDetailsService userDetailsService;

@Bean
public DaoAuthenticationProvider authProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(encoder());
    return authProvider;
}

La configuration de la sécurité est simple:

  • nous injectons notre implémentation du service de détails des utilisateurs

  • nous définissons un fournisseur d'authentification qui référence notre service de détails

  • nous activons également l'encodeur de mot de passe

Et enfin, nous devonsreference this auth provider dans notre configuration XML de sécurité:


    

Ou, si vous utilisez la configuration Java:

@Configuration
@ComponentScan(basePackages = { "org.example.security" })
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider());
    }

    ...
}

5. Conclusion

Ce didacticiel rapide poursuit la série d’enregistrements en montrant comment stocker correctement le mot de passe dans la base de données en tirant parti de la mise en œuvre simple mais très puissante de BCrypt.

Lesfull implementation de ce didacticiel d'enregistrement avec Spring Security se trouvent dansthe GitHub project - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.