@@ -295,8 +295,8 @@ method that fits most use-cases::
295295 use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
296296 use Symfony\Component\Security\Core\Exception\AuthenticationException;
297297 use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
298- use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
299298 use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
299+ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
300300 use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
301301 use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
302302
@@ -328,14 +328,7 @@ method that fits most use-cases::
328328 throw new CustomUserMessageAuthenticationException('No API token provided');
329329 }
330330
331- $user = $this->entityManager->getRepository(User::class)
332- ->findOneBy(['apiToken' => $apiToken])
333- ;
334- if (null === $user) {
335- throw new UsernameNotFoundException();
336- }
337-
338- return new SelfValidatingPassport($user);
331+ return new SelfValidatingPassport(new UserBadge($apiToken));
339332 }
340333
341334 public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
@@ -442,23 +435,61 @@ into a security
442435Security Passports
443436~~~~~~~~~~~~~~~~~~
444437
438+ ..versionadded ::5.2
439+
440+ The ``UserBadge `` was introduced in Symfony 5.2. Prior to 5.2, the user
441+ instance was provided directly to the passport.
442+
445443A passport is an object that contains the user that will be authenticated as
446444well as other pieces of information, like whether a password should be checked
447445or if "remember me" functionality should be enabled.
448446
449447The default
450448:class: `Symfony\\ Component\\ Security\\ Http\\ Authenticator\\ Passport\\ Passport `
451- requires a user object and credentials. The following credential classes
452- are supported by default:
449+ requires a user and credentials.
450+
451+ Use the
452+ :class: `Symfony\\ Component\\ Security\\ Http\\ Authenticator\\ Passport\\ Badge\\ UserBadge `
453+ to attach the user to the passport. The ``UserBadge `` requires a user
454+ identifier (e.g. the username or email), which is used to load the user
455+ using:ref: `the user provider <security-user-providers >`::
453456
457+ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
458+
459+ // ...
460+ $passport = new Passport(new UserBadge($email), $credentials);
461+
462+ ..note ::
463+
464+ You can optionally pass a user loader as second argument to the
465+ ``UserBadge ``. This callable receives the ``$userIdentifier ``
466+ and must return a ``UserInterface `` object (otherwise a
467+ ``UsernameNotFoundException `` is thrown)::
468+
469+ // ...
470+ $passport = new Passport(
471+ new UserBadge($email, function ($userIdentifier) {
472+ return $this->userRepository->findOneBy(['email' => $userIdentifier]);
473+ }),
474+ $credentials
475+ );
476+
477+ The following credential classes are supported by default:
454478
455479:class: `Symfony\\ Component\\ Security\\ Http\\ Authenticator\\ Passport\\ Credentials\\ PasswordCredentials `
456480 This requires a plaintext ``$password ``, which is validated using the
457- :ref: `password encoder configured for the user <security-encoding-user-password >`.
481+ :ref: `password encoder configured for the user <security-encoding-user-password >`::
482+
483+ use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
484+
485+ // ...
486+ return new Passport($user, new PasswordCredentials($plaintextPassword));
458487
459488:class: `Symfony\\ Component\\ Security\\ Http\\ Authenticator\\ Passport\\ Credentials\\ CustomCredentials `
460489 Allows a custom closure to check credentials::
461490
491+ use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials;
492+
462493 // ...
463494 return new Passport($user, new CustomCredentials(
464495 // If this function returns anything else than `true`, the credentials
@@ -472,12 +503,15 @@ are supported by default:
472503 $apiToken
473504 ));
474505
475- ..note ::
476506
477- If you don't need any credentials to be checked (e.g. a JWT token), you
478- can use the
479- :class: `Symfony\\ Component\\ Security\\ Http\\ Authenticator\\ Passport\\ SelfValidatingPassport `.
480- This class only requires a user and optionally `Passport Badges `_.
507+ Self Validating Passport
508+ ........................
509+
510+ If you don't need any credentials to be checked (e.g. when using API
511+ tokens), you can use the
512+ :class: `Symfony\\ Component\\ Security\\ Http\\ Authenticator\\ Passport\\ SelfValidatingPassport `.
513+ This class only requires a ``UserBadge `` object and optionally `Passport
514+ Badges `_.
481515
482516Passport Badges
483517~~~~~~~~~~~~~~~
@@ -507,16 +541,21 @@ the following badges are supported:
507541 initiated). This skips the
508542:doc: `pre-authentication user checker </security/user_checkers >`.
509543
510- For instance, if you want to add CSRF and password migration to your custom
511- authenticator, you would initialize the passport like this::
544+ ..versionadded ::5.2
545+
546+ Since 5.2, the ``PasswordUpgradeBadge `` is automatically added to
547+ the passport if the passport has ``PasswordCredentials ``.
548+
549+ For instance, if you want to add CSRF to your custom authenticator, you
550+ would initialize the passport like this::
512551
513552 // src/Service/LoginAuthenticator.php
514553 namespace App\Service;
515554
516555 // ...
517556 use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
518557 use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
519- use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PasswordUpgradeBadge ;
558+ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge ;
520559 use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
521560 use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
522561
@@ -528,14 +567,13 @@ authenticator, you would initialize the passport like this::
528567 $username = $request->request->get('username');
529568 $csrfToken = $request->request->get('csrf_token');
530569
531- // ... get the $user from the $username and validate no
532- // parameter is empty
570+ // ... validate no parameter is empty
533571
534- return new Passport($user, new PasswordCredentials($password), [
535- // $this->userRepository must implement PasswordUpgraderInterface
536- newPasswordUpgradeBadge ($password, $this->userRepository ),
537- new CsrfTokenBadge('login', $csrfToken),
538- ] );
572+ return new Passport(
573+ new UserBadge($user),
574+ newPasswordCredentials ($password),
575+ [ new CsrfTokenBadge('login', $csrfToken)]
576+ );
539577 }
540578 }
541579
@@ -547,7 +585,7 @@ authenticator, you would initialize the passport like this::
547585 ``createAuthenticatedToken() ``)::
548586
549587 // ...
550- use Symfony\Component\Security\Core\Authentication\Token\TokenInterface ;
588+ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge ;
551589
552590 class LoginAuthenticator extends AbstractAuthenticator
553591 {
@@ -557,7 +595,7 @@ authenticator, you would initialize the passport like this::
557595 {
558596 // ... process the request
559597
560- $passport = new SelfValidatingPassport($username, []);
598+ $passport = new SelfValidatingPassport(new UserBadge( $username) , []);
561599
562600 // set a custom attribute (e.g. scope)
563601 $passport->setAttribute('scope', $oauthScope);