@@ -135,6 +135,42 @@ unauthenticated access (e.g. the login page):
135135 ],
136136 ]);
137137
138+ Granting Anonymous Users Access in a Custom Voter
139+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
140+
141+ .. versionadded :: 5.2
142+
143+ The ``NullToken `` class was introduced in Symfony 5.2.
144+
145+ If you're using a :doc: `custom voter </security/voters >`, you can allow
146+ anonymous users access by checking for a special
147+ :class: `Symfony\\ Component\\ Security\\ Core\\ Authentication\\ Token\\ NullToken `. This token is used
148+ in the voters to represent the unauthenticated access::
149+
150+ // src/Security/PostVoter.php
151+ namespace App\Security;
152+
153+ // ...
154+ use Symfony\Component\Security\Core\Authentication\Token\NullToken;
155+ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
156+ use Symfony\Component\Security\Core\Authorization\Voter\Voter;
157+
158+ class PostVoter extends Voter
159+ {
160+ // ...
161+
162+ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
163+ {
164+ // ...
165+
166+ if ($token instanceof NullToken) {
167+ // the user is not authenticated, e.g. only allow them to
168+ // see public posts
169+ return $subject->isPublic();
170+ }
171+ }
172+ }
173+
138174.. _authenticators-required-entry-point :
139175
140176Configuring the Authentication Entry Point
@@ -502,3 +538,40 @@ authenticator, you would initialize the passport like this::
502538 ]);
503539 }
504540 }
541+
542+ .. tip ::
543+
544+ Besides badges, passports can define attributes, which allows the
545+ ``authenticate() `` method to store arbitrary information in the
546+ passport to access it from other authenticator methods (e.g.
547+ ``createAuthenticatedToken() ``)::
548+
549+ // ...
550+ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
551+
552+ class LoginAuthenticator extends AbstractAuthenticator
553+ {
554+ // ...
555+
556+ public function authenticate(Request $request): PassportInterface
557+ {
558+ // ... process the request
559+
560+ $passport = new SelfValidatingPassport($username, []);
561+
562+ // set a custom attribute (e.g. scope)
563+ $passport->setAttribute('scope', $oauthScope);
564+
565+ return $passport;
566+ }
567+
568+ public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface
569+ {
570+ // read the attribute value
571+ return new CustomOauthToken($passport->getUser(), $passport->getAttribute('scope'));
572+ }
573+ }
574+
575+ .. versionadded :: 5.2
576+
577+ Passport attributes were introduced in Symfony 5.2.
0 commit comments