diff options
author | Ryan Weaver <ryan@thatsquality.com> | 2015-05-17 17:29:55 -0400 |
---|---|---|
committer | Ryan Weaver <ryan@thatsquality.com> | 2015-09-20 19:24:21 -0400 |
commit | 93a1b25f892c82b07cda5fd876f64c64585ba3a8 (patch) | |
tree | 7098adb2b41f2f9b3b7f54c1207acadde8cc85de /Guard | |
parent | 87752f2f460528718bbb691b1739a32368141c28 (diff) | |
download | symfony-security-93a1b25f892c82b07cda5fd876f64c64585ba3a8.zip symfony-security-93a1b25f892c82b07cda5fd876f64c64585ba3a8.tar.gz symfony-security-93a1b25f892c82b07cda5fd876f64c64585ba3a8.tar.bz2 |
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
Diffstat (limited to 'Guard')
-rw-r--r-- | Guard/Provider/GuardAuthenticationProvider.php | 13 | ||||
-rw-r--r-- | Guard/Tests/Provider/GuardAuthenticationProviderTest.php | 18 |
2 files changed, 31 insertions, 0 deletions
diff --git a/Guard/Provider/GuardAuthenticationProvider.php b/Guard/Provider/GuardAuthenticationProvider.php index 150943d..aa9a78d 100644 --- a/Guard/Provider/GuardAuthenticationProvider.php +++ b/Guard/Provider/GuardAuthenticationProvider.php @@ -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 diff --git a/Guard/Tests/Provider/GuardAuthenticationProviderTest.php b/Guard/Tests/Provider/GuardAuthenticationProviderTest.php index 7df3ecb..99e9b5d 100644 --- a/Guard/Tests/Provider/GuardAuthenticationProviderTest.php +++ b/Guard/Tests/Provider/GuardAuthenticationProviderTest.php @@ -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'); |