Fixing a bug where having an authentication failure would log you out.
This solution is a copy of what AbstractAuthenticationListener does. Scenario: 1) Login 2) Go back to the log in page 3) Put in a bad user/pass You *should* still be logged in after a failed attempt. This commit gives that behavior.
This commit is contained in:
parent
396a1622dc
commit
302235e6e5
@ -117,7 +117,7 @@ class GuardAuthenticationListener implements ListenerInterface
|
|||||||
$this->logger->info('Guard authentication failed.', array('exception' => $e, 'authenticator' => get_class($guardAuthenticator)));
|
$this->logger->info('Guard authentication failed.', array('exception' => $e, 'authenticator' => get_class($guardAuthenticator)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->guardHandler->handleAuthenticationFailure($e, $request, $guardAuthenticator);
|
$response = $this->guardHandler->handleAuthenticationFailure($e, $request, $guardAuthenticator, $this->providerKey);
|
||||||
|
|
||||||
if ($response instanceof Response) {
|
if ($response instanceof Response) {
|
||||||
$event->setResponse($response);
|
$event->setResponse($response);
|
||||||
|
@ -18,6 +18,7 @@ use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInt
|
|||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
|
||||||
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
||||||
use Symfony\Component\Security\Http\SecurityEvents;
|
use Symfony\Component\Security\Http\SecurityEvents;
|
||||||
|
|
||||||
@ -112,12 +113,16 @@ class GuardAuthenticatorHandler
|
|||||||
* @param AuthenticationException $authenticationException
|
* @param AuthenticationException $authenticationException
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param GuardAuthenticatorInterface $guardAuthenticator
|
* @param GuardAuthenticatorInterface $guardAuthenticator
|
||||||
|
* @param string $providerKey The key of the firewall
|
||||||
*
|
*
|
||||||
* @return null|Response
|
* @return null|Response
|
||||||
*/
|
*/
|
||||||
public function handleAuthenticationFailure(AuthenticationException $authenticationException, Request $request, GuardAuthenticatorInterface $guardAuthenticator)
|
public function handleAuthenticationFailure(AuthenticationException $authenticationException, Request $request, GuardAuthenticatorInterface $guardAuthenticator, $providerKey)
|
||||||
{
|
{
|
||||||
$this->tokenStorage->setToken(null);
|
$token = $this->tokenStorage->getToken();
|
||||||
|
if ($token instanceof PostAuthenticationGuardToken && $providerKey === $token->getProviderKey()) {
|
||||||
|
$this->tokenStorage->setToken(null);
|
||||||
|
}
|
||||||
|
|
||||||
$response = $guardAuthenticator->onAuthenticationFailure($request, $authenticationException);
|
$response = $guardAuthenticator->onAuthenticationFailure($request, $authenticationException);
|
||||||
if ($response instanceof Response || null === $response) {
|
if ($response instanceof Response || null === $response) {
|
||||||
|
@ -141,7 +141,7 @@ class GuardAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->guardAuthenticatorHandler
|
$this->guardAuthenticatorHandler
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('handleAuthenticationFailure')
|
->method('handleAuthenticationFailure')
|
||||||
->with($authException, $this->request, $authenticator);
|
->with($authException, $this->request, $authenticator, $providerKey);
|
||||||
|
|
||||||
$listener = new GuardAuthenticationListener(
|
$listener = new GuardAuthenticationListener(
|
||||||
$this->guardAuthenticatorHandler,
|
$this->guardAuthenticatorHandler,
|
||||||
|
@ -18,9 +18,6 @@ use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
|||||||
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
||||||
use Symfony\Component\Security\Http\SecurityEvents;
|
use Symfony\Component\Security\Http\SecurityEvents;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
|
||||||
*/
|
|
||||||
class GuardAuthenticatorHandlerTest extends \PHPUnit_Framework_TestCase
|
class GuardAuthenticatorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
private $tokenStorage;
|
private $tokenStorage;
|
||||||
@ -63,7 +60,8 @@ class GuardAuthenticatorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
public function testHandleAuthenticationFailure()
|
public function testHandleAuthenticationFailure()
|
||||||
{
|
{
|
||||||
$this->tokenStorage->expects($this->once())
|
// setToken() not called - getToken() will return null, so there's nothing to clear
|
||||||
|
$this->tokenStorage->expects($this->never())
|
||||||
->method('setToken')
|
->method('setToken')
|
||||||
->with(null);
|
->with(null);
|
||||||
$authException = new AuthenticationException('Bad password!');
|
$authException = new AuthenticationException('Bad password!');
|
||||||
@ -75,10 +73,54 @@ class GuardAuthenticatorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||||||
->will($this->returnValue($response));
|
->will($this->returnValue($response));
|
||||||
|
|
||||||
$handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher);
|
$handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher);
|
||||||
$actualResponse = $handler->handleAuthenticationFailure($authException, $this->request, $this->guardAuthenticator);
|
$actualResponse = $handler->handleAuthenticationFailure($authException, $this->request, $this->guardAuthenticator, 'firewall_provider_key');
|
||||||
$this->assertSame($response, $actualResponse);
|
$this->assertSame($response, $actualResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getTokenClearingTests
|
||||||
|
*/
|
||||||
|
public function testHandleAuthenticationClearsToken($tokenClass, $tokenProviderKey, $actualProviderKey, $shouldTokenBeCleared)
|
||||||
|
{
|
||||||
|
$token = $this->getMockBuilder($tokenClass)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$token->expects($this->any())
|
||||||
|
->method('getProviderKey')
|
||||||
|
->will($this->returnValue($tokenProviderKey));
|
||||||
|
|
||||||
|
// make the $token be the current token
|
||||||
|
$this->tokenStorage->expects($this->once())
|
||||||
|
->method('getToken')
|
||||||
|
->will($this->returnValue($token));
|
||||||
|
|
||||||
|
$this->tokenStorage->expects($shouldTokenBeCleared ? $this->once() : $this->never())
|
||||||
|
->method('setToken')
|
||||||
|
->with(null);
|
||||||
|
$authException = new AuthenticationException('Bad password!');
|
||||||
|
|
||||||
|
$response = new Response('Try again, but with the right password!');
|
||||||
|
$this->guardAuthenticator->expects($this->once())
|
||||||
|
->method('onAuthenticationFailure')
|
||||||
|
->with($this->request, $authException)
|
||||||
|
->will($this->returnValue($response));
|
||||||
|
|
||||||
|
$handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher);
|
||||||
|
$actualResponse = $handler->handleAuthenticationFailure($authException, $this->request, $this->guardAuthenticator, $actualProviderKey);
|
||||||
|
$this->assertSame($response, $actualResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTokenClearingTests()
|
||||||
|
{
|
||||||
|
$tests = array();
|
||||||
|
// correct token class and matching firewall => clear the token
|
||||||
|
$tests[] = array('Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken', 'the_firewall_key', 'the_firewall_key', true);
|
||||||
|
$tests[] = array('Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken', 'the_firewall_key', 'different_key', false);
|
||||||
|
$tests[] = array('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', 'the_firewall_key', 'the_firewall_key', false);
|
||||||
|
|
||||||
|
return $tests;
|
||||||
|
}
|
||||||
|
|
||||||
protected function setUp()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
$this->tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
|
$this->tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
|
||||||
|
Reference in New Issue
Block a user