Comprendre l'authentification de Symfony 5.1+

Voir la vidéo

Dans cette vidéo je vous propose de nous attarder un petit peu sur le composant Security et le processus d'authentification de Symfony qui est souvent la source de pas mal d'incompréhension.

Processus d'authentification

EntryPoint

Lorsqu'un utilisateur n'est pas authentifié et qu'il essaie d'accéder à une ressource protégée le système de point d'entrée va déterminer quoi faire. Pour cela on va utiliser une classe qui implémente l'interface AuthenticationEntryPointInterface et qui définit l'action à effectuer via la méthode start(Request $request, AuthenticationException $authException = null). Par exemple, dans le cas d'un formulaire de connexion on redirige l'utilisateur vers le formulaire de connexion.

public function start(Request $request, AuthenticationException $authException = null): Response
{
    $url = $this->getLoginUrl($request);
    return new RedirectResponse($url);
}

Authenticator

L'authenticator permet à l'utilisateur de démarrer le processus d'authentification. La classe en charge de cette authentification devra impélmenter l'interface AuthenticatorInterface. Une première méthode supports() permettra de déterminer si la requête courante est une requête d'authentification.

public function supports(Request $request): ?bool;

Si le retour de cette fonction est vrai alors l'authenticateur va déclencher le processus d'authentification via la méthode authenticate qui devra renvoyer un objet implémentant la PassportInterface.

public function authenticate(Request $request): PassportInterface
{
    $password = $request->request->get('password');
    $username = $request->request->get('username');
    $csrfToken = $request->request->get('csrf_token');

    return new Passport(
        new UserBadge($username),
        new PasswordCredentials($password),
        [new CsrfTokenBadge('login', $csrfToken)]
    );
}

Ce système de passeport a été ajouté avec Symfony 5.1 et va à terme remplacer l'ancien système d'authentification. Un passeport est un simple objet qui est accompagné de badges qui vont ensuite être utilisés par les écouteurs d'évènements qui se déclenchents lors du processus d'authentification.

  • Le UserBadge, recevra un loader, et sera capable de récupérer l'utilisateur pour la suite du processus.
  • Le PasswordCredentials, sera utilisé par le CheckCredientialsListener et validera les informations d'identification.
  • Les autres badges sont utilisés par d'autres listeners en fonction de la situation.

UserProvider

La prochaine étape est donc de récupérer l'utilisateur à partir de l'identifiant du UserBadge. Pour cela Symfony va utiliser un objet qui implémente l'interface UserProviderInterface (par défaut l'implémentation utilisée est EntityUserProvider). Cette méthode aura 2 méthodes principales.

  • loadUserByIdentifier, qui permet de récupérer l'utilisateur à partir de son identifiant (par défaut l'email).
  • refreshUser, qui permet de recharger l'utilisateur depuis le token.

Token

Une fois l'authentification terminée un token représentant les informations de connexion va être renvoyé par l'Authenticator via la méthode createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface (et sera ensuite sauvegardée en session dans le cas d'une connexion statefull). En général, le comportement offert par défaut est suffisant et on peut étendre de la class AbstractAuthenticator.

Navigation

Maintenant que vous êtes connecté, vous pouvez naviguer entre les pages et la session sera persistée. Pour détecter la session, Symfony utilise le ContextListener qui va détecter la présence du token en session et qui pourra déclencher le refraichissement de l'utilisateur gràce au provider (si vous avez l'attribut lazy ce processus n'est déclenché que lors de l'accès à l'utilisateur).

Publié
Technologies utilisées
Auteur :
Grafikart
Partager