Updating behavior to not continue after an authenticator has set the response

This mirrors the behavior in core: *if* a listener sets a response (on success or failure),
then the other listeners are not called. But if a response is *not* set
(which is sometimes the case for success, like in BasicAuthenticationListener),
then the other listeners are called, and can even fail.
This commit is contained in:
Ryan Weaver 2015-09-26 12:34:14 -04:00
parent 1d5557f37f
commit f403444cc0
2 changed files with 40 additions and 1 deletions

View File

@ -75,6 +75,12 @@ class GuardAuthenticationListener implements ListenerInterface
$uniqueGuardKey = $this->providerKey.'_'.$key;
$this->executeGuardAuthenticator($uniqueGuardKey, $guardAuthenticator, $event);
if ($event->hasResponse()) {
$this->logger->info(sprintf('The "%s" authenticator set the response. Any later authenticator will not be called', get_class($guardAuthenticator)));
break;
}
}
}

View File

@ -79,6 +79,36 @@ class GuardAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$listener->handle($this->event);
}
public function testHandleSuccessStopsAfterResponseIsSet()
{
$authenticator1 = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
$authenticator2 = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
// mock the first authenticator to fail, and set a Response
$authenticator1
->expects($this->once())
->method('getCredentials')
->willThrowException(new AuthenticationException());
$this->guardAuthenticatorHandler
->expects($this->once())
->method('handleAuthenticationFailure')
->willReturn(new Response());
// the second authenticator should *never* be called
$authenticator2
->expects($this->never())
->method('getCredentials');
$listener = new GuardAuthenticationListener(
$this->guardAuthenticatorHandler,
$this->authenticationManager,
'my_firewall',
array($authenticator1, $authenticator2),
$this->logger
);
$listener->handle($this->event);
}
public function testHandleSuccessWithRememberMe()
{
$authenticator = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
@ -201,7 +231,10 @@ class GuardAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$this->request = new Request(array(), array(), array(), array(), array(), array());
$this->event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false);
$this->event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->disableOriginalConstructor()
->setMethods(array('getRequest'))
->getMock();
$this->event
->expects($this->any())
->method('getRequest')