New in Symfony 8.2 (in development). Sudo mode tells you when the user proved their identity. A bank also wants to know how: a password is enough to check a balance, not to empty the account. Symfony 8.2 now records on the token every authentication method proven during the session, along with the time it was last used.
The token remembers the method
Each authenticator says so with a badge on the passport, using the names from RFC 8176, gathered in AuthenticationMethod:
return new Passport( new UserBadge($username), new CustomCredentials($verify, $code), [new AuthenticationMethodBadge(AuthenticationMethod::SMS)], );
form_login, json_login and http_basic already do it, with AuthenticationMethod::PASSWORD. When the same user authenticates a second time, Symfony adds the new proof to the previous ones:
$token->getAuthenticationProofs(); // ['pwd' => 1792300000, 'sms' => 1792300060]
The method as the key, the Unix timestamp of its last use as the value. A voter just has to look.
Your task
Ada's bank (ada / lovelace) has a password login, a /verification page that sends a code by SMS (the fake carrier always sends 314159), and transfers open to any logged-in session. /accounts shows the session's proofs: you'll see yours appear.
CodeSmsAuthenticatorhandles the code form. It checks the code of the user who is already logged in and says they authenticated by SMS. Without a password given first, a code logs nobody in.- Declare it on the
mainfirewall, next toform_login. CodeSmsRecentVotergrantsRECENT_SMS_CODEwhen the token carries an SMS proof less than five minutes old.- Transfers require
RECENT_SMS_CODE. The rest of the account is fine with the password.
For now, Ada gets a 403 if she hasn't entered a code: the next exercise will send her to the code form instead.