feature #37917 [Security] Pass Passport to LoginFailureEvent (ihmels)

This PR was merged into the 5.2-dev branch.

Discussion
----------

[Security] Pass Passport to LoginFailureEvent

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | Fix #37585
| License       | MIT
| Doc PR        | -

This changes passes a `Passport` to the `LoginFailureEvent`.

Commits
-------

d23434bc23 [Security] Pass Passport to LoginFailureEvent
This commit is contained in:
Fabien Potencier 2020-08-23 09:59:17 +02:00
commit a8abd81840
4 changed files with 16 additions and 5 deletions

View File

@ -7,6 +7,7 @@ CHANGELOG
* Added attributes on `Passport`
* Changed `AuthorizationChecker` to call the access decision manager in unauthenticated sessions with a `NullToken`
* [BC break] Removed `AccessListener::PUBLIC_ACCESS` in favor of `AuthenticatedVoter::PUBLIC_ACCESS`
* Added `Passport` to `LoginFailureEvent`.
5.1.0
-----

View File

@ -158,6 +158,8 @@ class AuthenticatorManager implements AuthenticatorManagerInterface, UserAuthent
private function executeAuthenticator(AuthenticatorInterface $authenticator, Request $request): ?Response
{
$passport = null;
try {
// get the passport from the Authenticator
$passport = $authenticator->authenticate($request);
@ -198,7 +200,7 @@ class AuthenticatorManager implements AuthenticatorManagerInterface, UserAuthent
return null;
} catch (AuthenticationException $e) {
// oh no! Authentication failed!
$response = $this->handleAuthenticationFailure($e, $request, $authenticator);
$response = $this->handleAuthenticationFailure($e, $request, $authenticator, $passport);
if ($response instanceof Response) {
return $response;
}
@ -229,7 +231,7 @@ class AuthenticatorManager implements AuthenticatorManagerInterface, UserAuthent
/**
* Handles an authentication failure and returns the Response for the authenticator.
*/
private function handleAuthenticationFailure(AuthenticationException $authenticationException, Request $request, AuthenticatorInterface $authenticator): ?Response
private function handleAuthenticationFailure(AuthenticationException $authenticationException, Request $request, AuthenticatorInterface $authenticator, ?PassportInterface $passport): ?Response
{
if (null !== $this->logger) {
$this->logger->info('Authenticator failed.', ['exception' => $authenticationException, 'authenticator' => \get_class($authenticator)]);
@ -240,7 +242,7 @@ class AuthenticatorManager implements AuthenticatorManagerInterface, UserAuthent
$this->logger->debug('The "{authenticator}" authenticator set the failure response.', ['authenticator' => \get_class($authenticator)]);
}
$this->eventDispatcher->dispatch($loginFailureEvent = new LoginFailureEvent($authenticationException, $authenticator, $request, $response, $this->firewallName));
$this->eventDispatcher->dispatch($loginFailureEvent = new LoginFailureEvent($authenticationException, $authenticator, $request, $response, $this->firewallName, $passport));
// returning null is ok, it means they want the request to continue
return $loginFailureEvent->getResponse();

View File

@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
use Symfony\Contracts\EventDispatcher\Event;
/**
@ -32,14 +33,16 @@ class LoginFailureEvent extends Event
private $request;
private $response;
private $firewallName;
private $passport;
public function __construct(AuthenticationException $exception, AuthenticatorInterface $authenticator, Request $request, ?Response $response, string $firewallName)
public function __construct(AuthenticationException $exception, AuthenticatorInterface $authenticator, Request $request, ?Response $response, string $firewallName, ?PassportInterface $passport = null)
{
$this->exception = $exception;
$this->authenticator = $authenticator;
$this->request = $request;
$this->response = $response;
$this->firewallName = $firewallName;
$this->passport = $passport;
}
public function getException(): AuthenticationException
@ -71,4 +74,9 @@ class LoginFailureEvent extends Event
{
return $this->response;
}
public function getPassport(): ?PassportInterface
{
return $this->passport;
}
}

View File

@ -86,6 +86,6 @@ class RememberMeListenerTest extends TestCase
private function createLoginFailureEvent($providerKey)
{
return new LoginFailureEvent(new AuthenticationException(), $this->createMock(AuthenticatorInterface::class), $this->request, null, $providerKey);
return new LoginFailureEvent(new AuthenticationException(), $this->createMock(AuthenticatorInterface::class), $this->request, null, $providerKey, null);
}
}