diff options
author | alcaeus <git@alcaeus.org> | 2013-06-14 20:11:03 +0200 |
---|---|---|
committer | alcaeus <git@alcaeus.org> | 2013-07-19 23:56:43 +0200 |
commit | 73f4ea78eb4af288880ea99482f2542fa04b6c64 (patch) | |
tree | f9580fd9089f7e8be7c19380430b922d57361a5c /Http | |
parent | b98d50b0b06fa2e4541c2a3ec59d69591418da80 (diff) | |
download | symfony-security-73f4ea78eb4af288880ea99482f2542fa04b6c64.zip symfony-security-73f4ea78eb4af288880ea99482f2542fa04b6c64.tar.gz symfony-security-73f4ea78eb4af288880ea99482f2542fa04b6c64.tar.bz2 |
[Security] fixed issue where authentication listeners clear unrelated tokens
This commit fixes an issue where authentication listeners clear all security tokens in case of authentication failure.
This behavior makes it impossible to combine certain authentication mechanisms, notably x509 with form-based login.
Diffstat (limited to 'Http')
-rw-r--r-- | Http/Firewall/AbstractAuthenticationListener.php | 5 | ||||
-rw-r--r-- | Http/Firewall/AbstractPreAuthenticatedListener.php | 19 | ||||
-rw-r--r-- | Http/Firewall/BasicAuthenticationListener.php | 5 | ||||
-rw-r--r-- | Http/Firewall/DigestAuthenticationListener.php | 5 |
4 files changed, 30 insertions, 4 deletions
diff --git a/Http/Firewall/AbstractAuthenticationListener.php b/Http/Firewall/AbstractAuthenticationListener.php index d33c0f7..384f7ce 100644 --- a/Http/Firewall/AbstractAuthenticationListener.php +++ b/Http/Firewall/AbstractAuthenticationListener.php @@ -186,7 +186,10 @@ abstract class AbstractAuthenticationListener implements ListenerInterface $this->logger->info(sprintf('Authentication request failed: %s', $failed->getMessage())); } - $this->securityContext->setToken(null); + $token = $this->securityContext->getToken(); + if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey()) { + $this->securityContext->setToken(null); + } $response = $this->failureHandler->onAuthenticationFailure($request, $failed); diff --git a/Http/Firewall/AbstractPreAuthenticatedListener.php b/Http/Firewall/AbstractPreAuthenticatedListener.php index c6e47d0..28f6411 100644 --- a/Http/Firewall/AbstractPreAuthenticatedListener.php +++ b/Http/Firewall/AbstractPreAuthenticatedListener.php @@ -21,6 +21,7 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; /** * AbstractPreAuthenticatedListener is the base class for all listener that @@ -59,7 +60,12 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface $this->logger->debug(sprintf('Checking secure context token: %s', $this->securityContext->getToken())); } - list($user, $credentials) = $this->getPreAuthenticatedData($request); + try { + list($user, $credentials) = $this->getPreAuthenticatedData($request); + } catch (BadCredentialsException $exception) { + $this->clearToken(); + return; + } if (null !== $token = $this->securityContext->getToken()) { if ($token instanceof PreAuthenticatedToken && $this->providerKey == $token->getProviderKey() && $token->isAuthenticated() && $token->getUsername() === $user) { @@ -84,6 +90,17 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface $this->dispatcher->dispatch(SecurityEvents::INTERACTIVE_LOGIN, $loginEvent); } } catch (AuthenticationException $failed) { + $this->clearToken(); + } + } + + /** + * Clears a PreAuthenticatedToken for this provider (if present) + */ + protected function clearToken() + { + $token = $this->securityContext->getToken(); + if ($token instanceof PreAuthenticatedToken && $this->providerKey === $token->getProviderKey()) { $this->securityContext->setToken(null); if (null !== $this->logger) { diff --git a/Http/Firewall/BasicAuthenticationListener.php b/Http/Firewall/BasicAuthenticationListener.php index 5b1c8b3..bfc4abc 100644 --- a/Http/Firewall/BasicAuthenticationListener.php +++ b/Http/Firewall/BasicAuthenticationListener.php @@ -74,7 +74,10 @@ class BasicAuthenticationListener implements ListenerInterface $token = $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $request->headers->get('PHP_AUTH_PW'), $this->providerKey)); $this->securityContext->setToken($token); } catch (AuthenticationException $failed) { - $this->securityContext->setToken(null); + $token = $this->securityContext->getToken(); + if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey()) { + $this->securityContext->setToken(null); + } if (null !== $this->logger) { $this->logger->info(sprintf('Authentication request failed for user "%s": %s', $username, $failed->getMessage())); diff --git a/Http/Firewall/DigestAuthenticationListener.php b/Http/Firewall/DigestAuthenticationListener.php index 7ab3dcf..ea85e77 100644 --- a/Http/Firewall/DigestAuthenticationListener.php +++ b/Http/Firewall/DigestAuthenticationListener.php @@ -124,7 +124,10 @@ class DigestAuthenticationListener implements ListenerInterface private function fail(GetResponseEvent $event, Request $request, AuthenticationException $authException) { - $this->securityContext->setToken(null); + $token = $this->securityContext->getToken(); + if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey()) { + $this->securityContext->setToken(null); + } if (null !== $this->logger) { $this->logger->info($authException); |