Symfony 8.2 Nouveauté Publié le

Redemander le bon facteur plutôt qu'un 403

Vote::requestReAuthentication() : votre voter peut renvoyer vers une nouvelle authentification, et le point d'entrée choisit laquelle.

Notions abordées : Security

Nouveau dans Symfony 8.2 (en développement). Avec le mode sudo, un refus de IS_AUTHENTICATED_RECENTLY renvoie, par le point d'entrée de réauthentification du pare-feu, vers une nouvelle authentification au lieu d'un 403. Symfony 8.2 ouvre ce mécanisme à vos attributs : un voter peut dire au pare-feu qu'une nouvelle preuve changerait sa réponse.

Le voter prévient le pare-feu

protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool
{
    if (/* la preuve attendue est là */) {
        return true;
    }

    $vote?->requestReAuthentication($attribute);

    return false;
}

Le pare-feu retient la page demandée, note l'attribut refusé dans la requête, puis appelle son point d'entrée de réauthentification, celui du mode sudo :

$refuse = $request->attributes->get(SecurityRequestAttributes::RE_AUTHENTICATION_ATTRIBUTE);

Le point d'entrée peut ainsi redemander la bonne preuve : un code pour un virement, le mot de passe pour le reste. Ce partage est notre choix, pas une règle de Symfony : IS_AUTHENTICATED_RECENTLY regarde la preuve la plus récente, quelle que soit sa méthode.

Deux limites. Ne demandez une nouvelle preuve que si elle peut changer la réponse : à qui ne pourra jamais la fournir, un 403 est plus honnête qu'une boucle. Et le mécanisme ne joue que si un seul attribut est refusé : un contrôle qui en combine plusieurs donne toujours un 403.

À faire

La banque de l'exercice précédent : Ada (ada / lovelace) et Linus (linus / torvalds) reçoivent leurs codes par SMS, Grace (grace / hopper) n'a pas donné de téléphone. Sans code récent, /virements répond 403 à tous les trois. /coordonnees demande IS_AUTHENTICATED_RECENTLY.

  1. CodeSmsRecentVoter demande une nouvelle authentification quand il refuse CODE_SMS_RECENT, mais seulement à qui peut recevoir un code. Grace garde son 403.
  2. DemanderUnePreuve envoie vers le formulaire du code quand c'est CODE_SMS_RECENT qui a été refusé, vers la page de connexion sinon.
  3. Déclarez-le comme point d'entrée de réauthentification du pare-feu main.

Une fois le code saisi, Ada revient sur son virement.

D'où vient la fonctionnalité : la pull request d'origine.