J'essaie d'enregistrer des données supplémentaires dans l'objet principal de l'utilisateur.
Ce que j'ai fait, c'est:
implémenter l'interface "UserDetails" à ma classe d'utilisateurs existante où mes données supplémentaires sont enregistrées (comme l'adresse e-mail, etc.).
@Entity
public class User implements UserDetails {
J'ai ensuite créé une implémentation UserDetailsService:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
UserDAO userDAO;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
User user = userDAO.findOneByUsername(username);
if (user == null)
throw new UsernameNotFoundException("username " + username
+ " not found");
System.out.println("---------------------> FOUND ------------->"
+ user.getEmail());
return user;
}
}
La dernière étape consistait à ajouter UserDetailsService dans ma configuration de sécurité.
@Configuration
@EnableWebMvcSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService());
// ...
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.userDetailsService(userDetailsService());
// ...
}
@Override
protected UserDetailsService userDetailsService() {
return userDetailsService;
}
Je vois dans ma console que "loadUserByName" est appelé deux fois (à cause de la sortie "Trouvé").
Lorsque j'essaie d'accéder à l'objet principal dans mon contrôleur ->
System.out.println(SecurityContextHolder.getContext()
.getAuthentication().getPrincipal());
Je ne reçois pas mes données supplémentaires. Lorsque j'essaie de le diffuser sur mon objet utilisateur, j'obtiens une exception de diffusion impossible.
Y a-t-il quelque chose qui me manque ??
Merci d'avance.
D'accord. Mon problème était caché dans le code que je n'ai pas publié.
Je pensais que ce service de détails ne sert qu'à obtenir des détails supplémentaires, mais il est utilisé pour la connexion elle-même.
J'avais configuré "jdbcAuthentication" en plus et le printemps semblait toujours l'utiliser.
Maintenant que je n'ai obtenu que la configuration de detailsService, tout fonctionne bien.
éditer.:
donc je n'ai eu qu'à supprimer ce code:
auth.jdbcAuthentication() .dataSource(dataSource)
* .passwordEncoder(passwordEncoder) .usersByUsernameQuery(
// ....
Et maintenant, cela fonctionne également avec mon code dans la question ci-dessus.
Créer une classe d'extension:
public class CustomUserDetails extends org.springframework.security.core.userdetails.User{
private User user;
public CustomUserDetails(User user, Collection<? extends GrantedAuthority> authorities) {
super(user.getName(), user.getPassword(), authorities);
this.user = user;
}
public CustomUserDetails(User user, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
super(user.getName(), user.getPassword(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
this.user = user;
}
public User getUser() {
return user;
}
}
Ajoutez-le ensuite à UserDetailsService:
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException, DataAccessException {
UserDetails userDetails = null;
User user = userService.getByLogin(login);
userDetails = new CustomUserDetails(user,
true, true, true, true,
getAuthorities(user.getRole()));
return userDetails;
}
Tu piges!
(CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()