Récupérer les informations utilisateur dans Spring Security

Récupérer les informations utilisateur dans Spring Security

1. Vue d'ensemble

Cet article montrera commentretrieve the user details in Spring Security.

L'utilisateur actuellement authentifié est disponible via un certain nombre de mécanismes différents dans Spring - voyons d'abord la solution la plus courante - l'accès par programme.

Lectures complémentaires:

Gardez une trace des utilisateurs connectés avec Spring Security

Un guide rapide pour suivre les utilisateurs connectés dans une application créée à l'aide de Spring Security.

Read more

Spring Security - Rôles et privilèges

Comment mapper des rôles et des privilèges pour une application Spring Security: la configuration, l’authentification et le processus d’enregistrement.

Read more

Spring Security - Réinitialiser votre mot de passe

Chaque application doit permettre aux utilisateurs de changer leur propre mot de passe au cas où ils l'oublieraient.

Read more

2. Obtenez l'utilisateur dans un bean

Le moyen le plus simple de récupérer le principal actuellement authentifié est via un appel statique auxSecurityContextHolder:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();

Une amélioration de cet extrait vérifie d'abord s'il y a un utilisateur authentifié avant d'essayer d'y accéder:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication instanceof AnonymousAuthenticationToken)) {
    String currentUserName = authentication.getName();
    return currentUserName;
}

Un appel statique comme celui-ci présente bien sûr des inconvénients: une testabilité réduite du code est l’un des plus évidents. Au lieu de cela, nous explorerons des solutions alternatives pour cette exigence très courante.

3. Obtenez l'utilisateur dans un contrôleur

Dans un bean annoté@Controller, il existe des options supplémentaires. The principal can be defined directly as a method argument et il sera correctement résolu par le framework:

@Controller
public class SecurityController {

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    @ResponseBody
    public String currentUserName(Principal principal) {
        return principal.getName();
    }
}

Alternativement,we can also use the authentication token:

@Controller
public class SecurityController {

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    @ResponseBody
    public String currentUserName(Authentication authentication) {
        return authentication.getName();
    }
}

L'API de la classeAuthentication est très ouverte pour que le framework reste le plus flexible possible. Pour cette raison,the Spring Security principal can only be retrieved as an Object and needs to be cast to the correct UserDetails instance:

UserDetails userDetails = (UserDetails) authentication.getPrincipal();
System.out.println("User has authorities: " + userDetails.getAuthorities());

Et enfin, directementfrom the HTTP request:

@Controller
public class GetUserWithHTTPServletRequestController {

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    @ResponseBody
    public String currentUserNameSimple(HttpServletRequest request) {
        Principal principal = request.getUserPrincipal();
        return principal.getName();
    }
}

4. Obtenez l'utilisateur via une interface personnalisée

Pour tirer pleinement parti de l'injection de dépendances Spring et pouvoir récupérer l'authentification partout, pas seulement dans@Controller beans, nous devons masquer l'accès statique derrière une simple façade:

public interface IAuthenticationFacade {
    Authentication getAuthentication();
}
@Component
public class AuthenticationFacade implements IAuthenticationFacade {

    @Override
    public Authentication getAuthentication() {
        return SecurityContextHolder.getContext().getAuthentication();
    }
}

La façade expose l'objetAuthentication tout en masquant l'état statique et en maintenant le code découplé et entièrement testable:

@Controller
public class GetUserWithCustomInterfaceController {
    @Autowired
    private IAuthenticationFacade authenticationFacade;

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    @ResponseBody
    public String currentUserNameSimple() {
        Authentication authentication = authenticationFacade.getAuthentication();
        return authentication.getName();
    }
}

5. Obtenez l'utilisateur dans JSP

Le principal actuellement authentifiécan also be accessed in JSP pages, en tirant parti du support de taglib de sécurité à ressort. Tout d'abord, nous devons définir la balise dans la page:

<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>

Ensuite, nous pouvonsrefer to the principal:


    authenticated as 

6. Obtenez l'utilisateur dans Thymeleaf

Thymeleaf est un moteur de création de modèles Web moderne côté serveur, avec un bon frameworkintegration with the Spring MVC. Voyons comment accéder au principal actuellement authentifié dans une page avec le moteur Thymeleaf.

Tout d'abord, nous devons ajouter les dépendancesthymeleaf-spring5 etthymeleaf-extras-springsecurity5 pour intégrer Thymeleaf à Spring Security:


    org.thymeleaf.extras
    thymeleaf-extras-springsecurity5


    org.thymeleaf
    thymeleaf-spring5

Maintenantwe can refer to the principal in the HTML page using the sec:authorize attribute:



    
Authenticated as

7. Conclusion

Cet article a montré comment obtenir les informations utilisateur dans une application Spring, en commençant par le mécanisme d'accès statique commun, suivi de plusieurs méthodes plus efficaces pour injecter le principal.

L'implémentation de ces exemples peut être trouvée dansthe GitHub project - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel. Lorsque le projet s'exécute localement, la page d'accueil HTML peut être consultée à l'adresse suivante:

http://localhost:8080/spring-security-rest-custom/foos/1