Il est possible d'avoir plusieurs AuthenticationProvider afin de gérer différents type d'authentification :
- Par mot de passe
- OAuth2
- LDAP
- custom
Ainsi, dans cette partie nous allons voir comment configurer notre application pour qu'elle accepte à la fois l'authentification par :
- mot de passe en retrouvant l'utilisateur en base de données
- en mémoire, nous allons enregistrer un utilisateur en mémoire directement
- en customisant notre propre provider
AuthenticationManager
Nous devons donc configurer notre AuthenticationManager
pour qu'il accepte différent type d'authentification. Pour ce faire nous allons nous aider de la classe AuthenticationManagerBuilder
class SecurityConfig {
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
private CustomAuthenticationProvider customAuthProvider;
@Bean
public AuthenticationManager authManager(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.userDetailsService(userDetailsService);
authenticationManagerBuilder.inMemoryAuthentication()
.withUser("memuser")
.password(passwordEncoder().encode("pass"))
.roles("USER");
authenticationManagerBuilder.authenticationProvider(customAuthProvider);
return authenticationManagerBuilder.build();
}
}
authenticationManagerBuilder.userDetailsService(userDetailsService);
permet d'ajouter l'authentification par user/password via la configuration d'un userDetailsService qui ira chercher en base de données les informations. Derrière cette méthode se cache la création de l'objetDaoAuthenticationProvider
authenticationManagerBuilder.inMemoryAuthentication()
permet d'ajouter un utilisateur en mémoire directementauthenticationManagerBuilder.authenticationProvider(customAuthProvider)
permet de créer notre propre provider
CustomAuthProvider
Classe simpliste, nous enregistrons les informations (user/password) directement dans le code afin de simplifier
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication auth)
throws AuthenticationException {
String username = auth.getName();
String password = auth.getCredentials()
.toString();
if ("externaluser".equals(username) && "pass".equals(password)) {
return new UsernamePasswordAuthenticationToken
(username, password, Collections.emptyList());
} else {
throw new
BadCredentialsException("External system authentication failed");
}
}
@Override
public boolean supports(Class<?> auth) {
return auth.equals(UsernamePasswordAuthenticationToken.class);
}
}
Conséquence
Maintenant nous avons trois moyens de nous authentifier
- Via les informations enregistrées en base
- En saisissant
memuser/pass
pour l'authentification en mémoire - En saisissant
externaluser/pass
pour l'authentification custom