19
19
use Symfony \Component \Security \Core \AuthenticationEvents ;
20
20
use Symfony \Component \Security \Core \Event \AuthenticationSuccessEvent ;
21
21
use Symfony \Component \Security \Core \Exception \AuthenticationException ;
22
- use Symfony \Component \Security \Core \Exception \BadCredentialsException ;
23
- use Symfony \Component \Security \Core \Exception \UsernameNotFoundException ;
24
22
use Symfony \Component \Security \Core \User \UserInterface ;
25
23
use Symfony \Component \Security \Http \Authenticator \AuthenticatorInterface ;
26
24
use 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 ;
27
29
use Symfony \Component \Security \Http \Event \InteractiveLoginEvent ;
28
30
use Symfony \Component \Security \Http \Event \LoginFailureEvent ;
29
31
use Symfony \Component \Security \Http \Event \LoginSuccessEvent ;
@@ -60,13 +62,16 @@ public function __construct(iterable $authenticators, TokenStorageInterface $tok
60
62
$ this ->eraseCredentials = $ eraseCredentials ;
61
63
}
62
64
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
64
69
{
65
70
// 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 );
67
72
68
73
// authenticate this in the system
69
- return $ this ->handleAuthenticationSuccess ($ token , $ request , $ authenticator );
74
+ return $ this ->handleAuthenticationSuccess ($ token , $ passport , $ request , $ authenticator );
70
75
}
71
76
72
77
public function supports (Request $ request ): ?bool
@@ -133,7 +138,7 @@ private function executeAuthenticators(array $authenticators, Request $request):
133
138
continue ;
134
139
}
135
140
136
- $ response = $ this ->executeAuthenticator ($ key , $ authenticator , $ request );
141
+ $ response = $ this ->executeAuthenticator ($ authenticator , $ request );
137
142
if (null !== $ response ) {
138
143
if (null !== $ this ->logger ) {
139
144
$ 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):
146
151
return null ;
147
152
}
148
153
149
- private function executeAuthenticator (string $ uniqueAuthenticatorKey , AuthenticatorInterface $ authenticator , Request $ request ): ?Response
154
+ private function executeAuthenticator (AuthenticatorInterface $ authenticator , Request $ request ): ?Response
150
155
{
151
156
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 );
155
163
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 ( );
158
166
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 ();
161
171
}
162
172
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
+ }
165
176
166
177
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 )]);
168
179
}
169
180
170
181
// success! (sets the token on the token storage, etc)
171
- $ response = $ this ->handleAuthenticationSuccess ($ token , $ request , $ authenticator );
182
+ $ response = $ this ->handleAuthenticationSuccess ($ authenticatedToken , $ passport , $ request , $ authenticator );
172
183
if ($ response instanceof Response) {
173
184
return $ response ;
174
185
}
@@ -189,35 +200,7 @@ private function executeAuthenticator(string $uniqueAuthenticatorKey, Authentica
189
200
}
190
201
}
191
202
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
221
204
{
222
205
$ this ->tokenStorage ->setToken ($ authenticatedToken );
223
206
@@ -227,7 +210,11 @@ private function handleAuthenticationSuccess(TokenInterface $authenticatedToken,
227
210
$ this ->eventDispatcher ->dispatch ($ loginEvent , SecurityEvents::INTERACTIVE_LOGIN );
228
211
}
229
212
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 ));
231
218
232
219
return $ loginSuccessEvent ->getResponse ();
233
220
}
0 commit comments