Properly handles "post auth" tokens that have become not authenticated
Here is the flow: A) You login using guard and are given a PostAuthGuardToken B) Your user changes between requests - AbstractToken::setUser() and hasUserChanged() - which results in the Token becoming "not authenticated" C) Something calls out to the security system, which then passes the no-longer-authed token back into the AuthenticationProviderManager D) Because the PostauthGuardToken implements GuardTokenInterface, the provider responds to it. But, seeing that this is a no-longer-authed PostAuthGuardToken, it returns an AnonymousToken, which triggers logout
This commit is contained in:
parent
873ed284d2
commit
180e2c7878
@ -55,6 +55,19 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface
|
||||
throw new \InvalidArgumentException('GuardAuthenticationProvider only supports NonAuthenticatedGuardToken');
|
||||
}
|
||||
|
||||
if (!$token instanceof PreAuthenticationGuardToken) {
|
||||
/*
|
||||
* The listener *only* passes PreAuthenticationGuardToken instances.
|
||||
* This means that an authenticated token (e.g. PostAuthenticationGuardToken)
|
||||
* is being passed here, which happens if that token becomes
|
||||
* "not authenticated" (e.g. happens if the user changes between
|
||||
* requests). In this case, the user should be logged out, so
|
||||
* we will return an AnonymousToken to accomplish that.
|
||||
*/
|
||||
|
||||
return new AnonymousToken($this->providerKey, 'anon.');
|
||||
}
|
||||
|
||||
// find the *one* GuardAuthenticator that this token originated from
|
||||
foreach ($this->guardAuthenticators as $key => $guardAuthenticator) {
|
||||
// get a key that's unique to *this* guard authenticator
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace Symfony\Component\Security\Guard\Tests\Provider;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
|
||||
use Symfony\Component\Security\Guard\Provider\GuardAuthenticationProvider;
|
||||
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
|
||||
|
||||
/**
|
||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||
@ -75,6 +77,22 @@ class GuardAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame($authedToken, $actualAuthedToken);
|
||||
}
|
||||
|
||||
public function testGuardWithNoLongerAuthenticatedTriggersLogout()
|
||||
{
|
||||
$providerKey = 'my_firewall_abc';
|
||||
|
||||
// create a token and mark it as NOT authenticated anymore
|
||||
// this mimics what would happen if a user "changed" between request
|
||||
$mockedUser = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
|
||||
$token = new PostAuthenticationGuardToken($mockedUser, $providerKey, array('ROLE_USER'));
|
||||
$token->setAuthenticated(false);
|
||||
|
||||
$provider = new GuardAuthenticationProvider(array(), $this->userProvider, $providerKey, $this->userChecker);
|
||||
$actualToken = $provider->authenticate($token);
|
||||
// this should return the anonymous user
|
||||
$this->assertEquals(new AnonymousToken($providerKey, 'anon.'), $actualToken);
|
||||
}
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
|
||||
|
Reference in New Issue
Block a user