Servlet Authentication Architecture
I. SecurityContextHolder et SecurityContext
Spring Security est un framework robuste qui permet la sécurisation des applications Java developpées avec le framework Spring. Spring Security dispose de plusieurs composants mais les deux composants SecurityContext et SecurityContextHolder sont essentiels pour comprendre et gérer l'authentification et récupérer les informations spécifiques à l'utilisateur à savoir de l'utilisateur actuellement connecté.
SecurityContextHolder
Cette classe contient le conteneur SecurityContext. L'objet SecurityContextHolder au sein d'une application Spring est l'endroit où Spring Security garde les détails de la personne authentifiée. L'objet Conteneur SecurityContext stocke les informations d'authentification et de sécurité de l'utilisateur actuellement connecté. En son sein l'objet SecurityContext contient un objet Authentication, qui représente l'objet "Principal" (l'utilisateur) et les droits qui lui sont accordés (rôles/autorisations). Spring Security ne se soucie pas de la manière dont le SecurityContextHolder est renseigné. S'il contient une valeur i.e un objet "Principal", celui-ci est utilisé comme utilisateur actuellement authentifié.
Le moyen le plus simple d'indiquer qu'un utilisateur est authentifié est de définir directement le SecurityContextHolder. Toutefois cette approche est rarement utilisée. Une instance de cette classe est l'objet central qui permet d'accéder aux informations générales relatives à la securité de l'utisateur acctuellement connécté dans une application basée sur Spring security.
.......
Exemples :
Premier exemple
Si on veut mettre à jour les valeurs des éléments de l'objet Authentication présent dans un context on peut procèder comme suit:
SecurityContext context = SecurityContextHolder.createEmptyContext(); // 1
Authentication authentication =
new TestingAuthenticationToken("username", "password", "ROLE_USER"); // 2
context.setAuthentication(authentication); // 3
SecurityContextHolder.setContext(context); // 4
Détails sur ce bout de code:
- On commence par créer un SecurityContext vide. Il est conseillé de créer une nouvelle instance SecurityContext au lieu d'utiliser SecurityContextHolder.getContext().setAuthentication(authentication) afin d'éviter les situations de concurrence entre plusieurs threads
- Ensuite, on crée un nouvel objet Authentication. Spring Security ne se soucie pas du type d'implémentation d'authentification défini sur le SecurityContext. Ici, nous utilisons TestingAuthenticationToken, car il est très simple. Un scénario de production plus courant est UsernamePasswordAuthenticationToken(userDetails, password, authorities).
- Puis on définit le SecurityContext sur le SecurityContextHolder ; Spring Security utilise ces informations pour l'autorisation
- Et enfin on fait la mise à jour par SecurityContextHolder.setContext(context);
Deuxième exemple: comment recupérer lutilisateur (usernamme) connecté
On peut récupérer le nom d'utilisateur de l'utilisateur connecté à partir du SecurityContextHolder comme suit :
import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; public String getLoggedInUsername() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && authentication.isAuthenticated()) { return authentication.getName(); // Retuurne l'utilisateur (the username) } return null; // aucun utilisateur (user) n'est indentifié }
Détails
- Access the SecurityContext: Use SecurityContextHolder.getContext() to retrieve the current SecurityContext....
- Get the Authentication Object: Call .getAuthentication() on the SecurityContext to retrieve the authentication details....
- Get the Username: Call .getName() on the Authentication object to get the principal's name....
SecurityContext
Comme on l'a dit ci-dessus le Conteneur SecurityContext est obtenu à partir de SecurityContextHolder et il contient l'interface Authentication qui représente l'authentification de l'utilisateur actuellement authentifié.
Authentication
L'interface Authentication est le type du paramètre d'entrée de la méthode authenticate(...) de l'interface AuthenticationManager mais aussi elle est le type de retour de cette méthode authenticate(...) pour fournir les informations d'identification qu'un utilisateur a besoin pour s'authentifier ou les informations d'identification de l'utilisateur actuel dans SecurityContext.
Cette interface Authentication remplit deux fonctions principales dans Spring Security :
- Elle permet une entrée dans AuthenticationManager pour fournir les identifiants de tout utilisateur pour s'authentifier. Dans ce cas, isAuthenticated() renvoie false.
- Elle permet de représenter l'utilisateur actuellement authentifié. Vous pouvez obtenir "l'authentifié" actuelle à partir de " SecurityContext".
Cette interface Authentication dérive de l'interface Principal (qui identifie l'utilisateur); Lors d'une authentification avec un nom d'utilisateur/mot de passe, il s'agit souvent d'une instance de UserDetails; elle permet aussi d'avoir accès aux credentials (souvent un mot de passe). Dans de nombreux cas, il est effacé après l'authentification de l'utilisateur afin d'éviter toute fuite d'informations cruciale ; les instances de GrantedAuthority sont des autorisations de haut niveau accordées à l'utilisateur. Les rôles en sont des exemples.
GrantedAuthority:
Une autorisation accordée au "Principal" ( voir Principal) sur l'authentification (c'est-à-dire les rôles, les portées, etc.) ....
AuthenticationManager:
l' API qui définit comment les Filtre de Spring Security procèdent pour l "Authentication" ....
ProviderManager:
Classe qui implémente l'interface AuthenticationProvider qui dérive de l'interface AuthenticationManager.
AuthenticationProvider :
interface implémentée par ProviderManager pour préciser le type spécial utilisé par l'interface Authentication.
.....