@@ -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
@@ -472,12 +465,23 @@ are supported by default:
472465 $apiToken
473466 ));
474467
475- ..note ::
476468
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 `_.
469+ Self Validating Passport
470+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
471+ If you don't need any credentials to be checked (e.g. a JWT token), you can use the
472+ :class: `Symfony\\ Component\\ Security\\ Http\\ Authenticator\\ Passport\\ SelfValidatingPassport `.
473+ This class only requires a ``UserBadge `` object and optionally `Passport Badges `_.
474+
475+ You can also pass a user loader to the ``UserBadge ``. This callable receives the
476+ ``$userIdentifier `` as argument and must return a ``UserInterface `` object
477+ (otherwise a ``UsernameNotFoundException `` is thrown). If this is not set,
478+ the default user provider will be used with ``$userIdentifier `` as username::
479+
480+ // ...
481+ return new SelfValidatingPassport(new UserBadge($email, function ($username) {
482+ return $this->userRepository->findOneBy(['email' => $username]);
483+ });
484+
481485
482486Passport Badges
483487~~~~~~~~~~~~~~~
@@ -547,7 +551,7 @@ authenticator, you would initialize the passport like this::
547551 ``createAuthenticatedToken() ``)::
548552
549553 // ...
550- use Symfony\Component\Security\Core\Authentication\Token\TokenInterface ;
554+ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge ;
551555
552556 class LoginAuthenticator extends AbstractAuthenticator
553557 {
@@ -557,7 +561,7 @@ authenticator, you would initialize the passport like this::
557561 {
558562 // ... process the request
559563
560- $passport = new SelfValidatingPassport($username, []);
564+ $passport = new SelfValidatingPassport(new UserBadge( $username) , []);
561565
562566 // set a custom attribute (e.g. scope)
563567 $passport->setAttribute('scope', $oauthScope);