From dd485f4c13fdf58b28a5f9c74f30736eb23af0b8 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Sun, 20 Sep 2015 20:41:52 -0400 Subject: [PATCH] Adding a new exception and throwing it when the User changes This is quite technical. As you can see in the provider, the method is called sometimes when the User changes, and so the token becomes de-authenticated (e.g. someone else changes the password between requests). In practice, the user should be unauthenticated. Using the anonymous token did this, but throwing an AccountStatusException seems like a better idea. It needs to be an AccountStatusException because the ExceptionListener from the Firewall looks for exceptions of this class and logs the user out when they are found (because this is their purpose). --- .../AuthenticationExpiredException.php | 31 +++++++++++++++++++ .../Provider/GuardAuthenticationProvider.php | 5 +-- .../GuardAuthenticationProviderTest.php | 5 +-- 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Component/Security/Core/Exception/AuthenticationExpiredException.php diff --git a/src/Symfony/Component/Security/Core/Exception/AuthenticationExpiredException.php b/src/Symfony/Component/Security/Core/Exception/AuthenticationExpiredException.php new file mode 100644 index 0000000000..caf2e6cc38 --- /dev/null +++ b/src/Symfony/Component/Security/Core/Exception/AuthenticationExpiredException.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\Exception; + +/** + * AuthenticationServiceException is thrown when an authenticated token becomes un-authentcated between requests. + * + * In practice, this is due to the User changing between requests (e.g. password changes), + * causes the token to become un-authenticated. + * + * @author Ryan Weaver + */ +class AuthenticationExpiredException extends AccountStatusException +{ + /** + * {@inheritdoc} + */ + public function getMessageKey() + { + return 'Authentication expired because your account information has changed.'; + } +} diff --git a/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php b/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php index 646eea9b59..2a58085bae 100644 --- a/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php +++ b/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php @@ -21,6 +21,7 @@ use Symfony\Component\Security\Core\User\UserCheckerInterface; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Exception\AuthenticationExpiredException; /** * Responsible for accepting the PreAuthenticationGuardToken and calling @@ -81,8 +82,8 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface return $token; } - // cause the logout - the token is not authenticated - return new AnonymousToken($this->providerKey, 'anon.'); + // this AccountStatusException causes the user to be logged out + throw new AuthenticationExpiredException(); } // find the *one* GuardAuthenticator that this token originated from diff --git a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php index 24c946d0e1..3bc002b269 100644 --- a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php +++ b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php @@ -81,6 +81,9 @@ class GuardAuthenticationProviderTest extends \PHPUnit_Framework_TestCase $this->assertSame($authedToken, $actualAuthedToken); } + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationExpiredException + */ public function testGuardWithNoLongerAuthenticatedTriggersLogout() { $providerKey = 'my_firewall_abc'; @@ -93,8 +96,6 @@ class GuardAuthenticationProviderTest extends \PHPUnit_Framework_TestCase $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()