Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 180e2c7

Browse files
committed
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
1 parent 873ed28 commit 180e2c7

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ public function authenticate(TokenInterface $token)
5555
throw new \InvalidArgumentException('GuardAuthenticationProvider only supports NonAuthenticatedGuardToken');
5656
}
5757

58+
if (!$token instanceof PreAuthenticationGuardToken) {
59+
/*
60+
* The listener *only* passes PreAuthenticationGuardToken instances.
61+
* This means that an authenticated token (e.g. PostAuthenticationGuardToken)
62+
* is being passed here, which happens if that token becomes
63+
* "not authenticated" (e.g. happens if the user changes between
64+
* requests). In this case, the user should be logged out, so
65+
* we will return an AnonymousToken to accomplish that.
66+
*/
67+
68+
return new AnonymousToken($this->providerKey, 'anon.');
69+
}
70+
5871
// find the *one* GuardAuthenticator that this token originated from
5972
foreach ($this->guardAuthenticators as $key => $guardAuthenticator) {
6073
// get a key that's unique to *this* guard authenticator

src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
namespace Symfony\Component\Security\Guard\Tests\Provider;
1313

14+
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
1415
use Symfony\Component\Security\Guard\Provider\GuardAuthenticationProvider;
16+
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
1517

1618
/**
1719
* @author Ryan Weaver <[email protected]>
@@ -75,6 +77,22 @@ public function testAuthenticate()
7577
$this->assertSame($authedToken, $actualAuthedToken);
7678
}
7779

80+
public function testGuardWithNoLongerAuthenticatedTriggersLogout()
81+
{
82+
$providerKey = 'my_firewall_abc';
83+
84+
// create a token and mark it as NOT authenticated anymore
85+
// this mimics what would happen if a user "changed" between request
86+
$mockedUser = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
87+
$token = new PostAuthenticationGuardToken($mockedUser, $providerKey, array('ROLE_USER'));
88+
$token->setAuthenticated(false);
89+
90+
$provider = new GuardAuthenticationProvider(array(), $this->userProvider, $providerKey, $this->userChecker);
91+
$actualToken = $provider->authenticate($token);
92+
// this should return the anonymous user
93+
$this->assertEquals(new AnonymousToken($providerKey, 'anon.'), $actualToken);
94+
}
95+
7896
protected function setUp()
7997
{
8098
$this->userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');

0 commit comments

Comments
 (0)