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');
|
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
|
// find the *one* GuardAuthenticator that this token originated from
|
||||||
foreach ($this->guardAuthenticators as $key => $guardAuthenticator) {
|
foreach ($this->guardAuthenticators as $key => $guardAuthenticator) {
|
||||||
// get a key that's unique to *this* guard authenticator
|
// get a key that's unique to *this* guard authenticator
|
||||||
|
@ -11,7 +11,9 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Security\Guard\Tests\Provider;
|
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\Provider\GuardAuthenticationProvider;
|
||||||
|
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||||
@ -75,6 +77,22 @@ class GuardAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertSame($authedToken, $actualAuthedToken);
|
$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()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
$this->userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
|
$this->userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
|
||||||
|
Reference in New Issue
Block a user