Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security] Pass Passport to LoginFailureEvent #37917

Merged
merged 1 commit into from Aug 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Symfony/Component/Security/CHANGELOG.md
Expand Up @@ -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
-----
Expand Down
Expand Up @@ -158,6 +158,8 @@ private function executeAuthenticators(array $authenticators, Request $request):

private function executeAuthenticator(AuthenticatorInterface $authenticator, Request $request): ?Response
{
$passport = null;

try {
// get the passport from the Authenticator
$passport = $authenticator->authenticate($request);
Expand Down Expand Up @@ -198,7 +200,7 @@ private function executeAuthenticator(AuthenticatorInterface $authenticator, Req
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;
}
Expand Down Expand Up @@ -229,7 +231,7 @@ private function handleAuthenticationSuccess(TokenInterface $authenticatedToken,
/**
* 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)]);
Expand All @@ -240,7 +242,7 @@ private function handleAuthenticationFailure(AuthenticationException $authentica
$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();
Expand Down
10 changes: 9 additions & 1 deletion src/Symfony/Component/Security/Http/Event/LoginFailureEvent.php
Expand Up @@ -15,6 +15,7 @@
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;

/**
Expand All @@ -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
Expand Down Expand Up @@ -71,4 +74,9 @@ public function getResponse(): ?Response
{
return $this->response;
}

public function getPassport(): ?PassportInterface
{
return $this->passport;
}
}
Expand Up @@ -86,6 +86,6 @@ private function createLoginSuccessfulEvent($providerKey, $response, PassportInt

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);
}
}