1919use Symfony \Component \Security \Core \AuthenticationEvents ;
2020use Symfony \Component \Security \Core \Event \AuthenticationSuccessEvent ;
2121use Symfony \Component \Security \Core \Exception \AuthenticationException ;
22- use Symfony \Component \Security \Core \Exception \BadCredentialsException ;
23- use Symfony \Component \Security \Core \Exception \UsernameNotFoundException ;
2422use Symfony \Component \Security \Core \User \UserInterface ;
2523use Symfony \Component \Security \Http \Authenticator \AuthenticatorInterface ;
2624use Symfony \Component \Security \Http \Authenticator \InteractiveAuthenticatorInterface ;
25+ use Symfony \Component \Security \Http \Authenticator \Passport \AnonymousPassport ;
26+ use Symfony \Component \Security \Http \Authenticator \Passport \Badge \BadgeInterface ;
27+ use Symfony \Component \Security \Http \Authenticator \Passport \PassportInterface ;
28+ use Symfony \Component \Security \Http \Authenticator \Passport \SelfValidatingPassport ;
2729use Symfony \Component \Security \Http \Event \InteractiveLoginEvent ;
2830use Symfony \Component \Security \Http \Event \LoginFailureEvent ;
2931use Symfony \Component \Security \Http \Event \LoginSuccessEvent ;
@@ -60,13 +62,16 @@ public function __construct(iterable $authenticators, TokenStorageInterface $tok
6062 $ this ->eraseCredentials = $ eraseCredentials ;
6163 }
6264
63- public function authenticateUser (UserInterface $ user , AuthenticatorInterface $ authenticator , Request $ request ): ?Response
65+ /**
66+ * @param BadgeInterface[] $badges Optionally, pass some Passport badges to use for the manual login
67+ */
68+ public function authenticateUser (UserInterface $ user , AuthenticatorInterface $ authenticator , Request $ request , array $ badges = []): ?Response
6469 {
6570 // create an authenticated token for the User
66- $ token = $ authenticator ->createAuthenticatedToken ($ user , $ this ->providerKey );
71+ $ token = $ authenticator ->createAuthenticatedToken ($ passport = new SelfValidatingPassport ( $ user, $ badges ) , $ this ->providerKey );
6772
6873 // authenticate this in the system
69- return $ this ->handleAuthenticationSuccess ($ token , $ request , $ authenticator );
74+ return $ this ->handleAuthenticationSuccess ($ token , $ passport , $ request , $ authenticator );
7075 }
7176
7277 public function supports (Request $ request ): ?bool
@@ -133,7 +138,7 @@ private function executeAuthenticators(array $authenticators, Request $request):
133138 continue ;
134139 }
135140
136- $ response = $ this ->executeAuthenticator ($ key , $ authenticator , $ request );
141+ $ response = $ this ->executeAuthenticator ($ authenticator , $ request );
137142 if (null !== $ response ) {
138143 if (null !== $ this ->logger ) {
139144 $ this ->logger ->debug ('The "{authenticator}" authenticator set the response. Any later authenticator will not be called ' , ['authenticator ' => \get_class ($ authenticator )]);
@@ -146,29 +151,35 @@ private function executeAuthenticators(array $authenticators, Request $request):
146151 return null ;
147152 }
148153
149- private function executeAuthenticator (string $ uniqueAuthenticatorKey , AuthenticatorInterface $ authenticator , Request $ request ): ?Response
154+ private function executeAuthenticator (AuthenticatorInterface $ authenticator , Request $ request ): ?Response
150155 {
151156 try {
152- if (null !== $ this ->logger ) {
153- $ this ->logger ->debug ('Calling getCredentials() on authenticator. ' , ['firewall_key ' => $ this ->providerKey , 'authenticator ' => \get_class ($ authenticator )]);
154- }
157+ // get the passport from the Authenticator
158+ $ passport = $ authenticator ->authenticate ($ request );
159+
160+ // check the passport (e.g. password checking)
161+ $ event = new VerifyAuthenticatorCredentialsEvent ($ authenticator , $ passport );
162+ $ this ->eventDispatcher ->dispatch ($ event );
155163
156- // allow the authenticator to fetch authentication info from the request
157- $ credentials = $ authenticator -> getCredentials ( $ request );
164+ // check if all badges are resolved
165+ $ passport -> checkIfCompletelyResolved ( );
158166
159- if (null === $ credentials ) {
160- throw new \UnexpectedValueException (sprintf ('The return value of "%1$s::getCredentials()" must not be null. Return false from "%1$s::supports()" instead. ' , \get_class ($ authenticator )));
167+ // create the authenticated token
168+ $ authenticatedToken = $ authenticator ->createAuthenticatedToken ($ passport , $ this ->providerKey );
169+ if (true === $ this ->eraseCredentials ) {
170+ $ authenticatedToken ->eraseCredentials ();
161171 }
162172
163- // authenticate the credentials (e.g. check password)
164- $ token = $ this ->authenticateViaAuthenticator ($ authenticator , $ credentials );
173+ if (null !== $ this ->eventDispatcher ) {
174+ $ this ->eventDispatcher ->dispatch (new AuthenticationSuccessEvent ($ authenticatedToken ), AuthenticationEvents::AUTHENTICATION_SUCCESS );
175+ }
165176
166177 if (null !== $ this ->logger ) {
167- $ this ->logger ->info ('Authenticator successful! ' , ['token ' => $ token , 'authenticator ' => \get_class ($ authenticator )]);
178+ $ this ->logger ->info ('Authenticator successful! ' , ['token ' => $ authenticatedToken , 'authenticator ' => \get_class ($ authenticator )]);
168179 }
169180
170181 // success! (sets the token on the token storage, etc)
171- $ response = $ this ->handleAuthenticationSuccess ($ token , $ request , $ authenticator );
182+ $ response = $ this ->handleAuthenticationSuccess ($ authenticatedToken , $ passport , $ request , $ authenticator );
172183 if ($ response instanceof Response) {
173184 return $ response ;
174185 }
@@ -189,35 +200,7 @@ private function executeAuthenticator(string $uniqueAuthenticatorKey, Authentica
189200 }
190201 }
191202
192- private function authenticateViaAuthenticator (AuthenticatorInterface $ authenticator , $ credentials ): TokenInterface
193- {
194- // get the user from the Authenticator
195- $ user = $ authenticator ->getUser ($ credentials );
196- if (null === $ user ) {
197- throw new UsernameNotFoundException (sprintf ('Null returned from "%s::getUser()". ' , \get_class ($ authenticator )));
198- }
199-
200- $ event = new VerifyAuthenticatorCredentialsEvent ($ authenticator , $ credentials , $ user );
201- $ this ->eventDispatcher ->dispatch ($ event );
202- if (true !== $ event ->areCredentialsValid ()) {
203- throw new BadCredentialsException (sprintf ('Authentication failed because "%s" did not approve the credentials. ' , \get_class ($ authenticator )));
204- }
205-
206- // turn the UserInterface into a TokenInterface
207- $ authenticatedToken = $ authenticator ->createAuthenticatedToken ($ user , $ this ->providerKey );
208-
209- if (true === $ this ->eraseCredentials ) {
210- $ authenticatedToken ->eraseCredentials ();
211- }
212-
213- if (null !== $ this ->eventDispatcher ) {
214- $ this ->eventDispatcher ->dispatch (new AuthenticationSuccessEvent ($ authenticatedToken ), AuthenticationEvents::AUTHENTICATION_SUCCESS );
215- }
216-
217- return $ authenticatedToken ;
218- }
219-
220- private function handleAuthenticationSuccess (TokenInterface $ authenticatedToken , Request $ request , AuthenticatorInterface $ authenticator ): ?Response
203+ private function handleAuthenticationSuccess (TokenInterface $ authenticatedToken , PassportInterface $ passport , Request $ request , AuthenticatorInterface $ authenticator ): ?Response
221204 {
222205 $ this ->tokenStorage ->setToken ($ authenticatedToken );
223206
@@ -227,7 +210,11 @@ private function handleAuthenticationSuccess(TokenInterface $authenticatedToken,
227210 $ this ->eventDispatcher ->dispatch ($ loginEvent , SecurityEvents::INTERACTIVE_LOGIN );
228211 }
229212
230- $ this ->eventDispatcher ->dispatch ($ loginSuccessEvent = new LoginSuccessEvent ($ authenticator , $ authenticatedToken , $ request , $ response , $ this ->providerKey ));
213+ if ($ passport instanceof AnonymousPassport) {
214+ return $ response ;
215+ }
216+
217+ $ this ->eventDispatcher ->dispatch ($ loginSuccessEvent = new LoginSuccessEvent ($ authenticator , $ passport , $ authenticatedToken , $ request , $ response , $ this ->firewallName ));
231218
232219 return $ loginSuccessEvent ->getResponse ();
233220 }
0 commit comments