From 873ed284d26b937efe4ead5c7b5abce13fea9d09 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Sun, 17 May 2015 17:27:01 -0400 Subject: [PATCH] Renaming the tokens to be clear they are "post" and "pre" auth - also adding an interface The reason is that the GuardAuthenticationProvider *must* respond to *all* tokens created by the system - both "pre auth" and "post auth" tokens. The reason is that if a "post auth" token becomes not authenticated (e.g. because the user changes between requests), then it may be passed to the provider system. If no providers respond (which was the case before this commit), then AuthenticationProviderManager throws an exception. The next commit will properly handle these "post auth" + "no-longer-authenticated" tokens, which should cause a log out. --- .../Security/Guard/AbstractGuardAuthenticator.php | 10 +++++----- .../Firewall/GuardAuthenticationListener.php | 4 ++-- .../Provider/GuardAuthenticationProvider.php | 15 +++++++++------ .../Firewall/GuardAuthenticationListenerTest.php | 4 ++-- .../Provider/GuardAuthenticationProviderTest.php | 12 ++++++------ .../Security/Guard/Token/GuardTokenInterface.php | 15 +++++++++++++++ ...Token.php => PostAuthenticationGuardToken.php} | 11 ++++------- ...dToken.php => PreAuthenticationGuardToken.php} | 4 ++-- 8 files changed, 45 insertions(+), 30 deletions(-) create mode 100644 src/Symfony/Component/Security/Guard/Token/GuardTokenInterface.php rename src/Symfony/Component/Security/Guard/Token/{GenericGuardToken.php => PostAuthenticationGuardToken.php} (87%) rename src/Symfony/Component/Security/Guard/Token/{NonAuthenticatedGuardToken.php => PreAuthenticationGuardToken.php} (88%) diff --git a/src/Symfony/Component/Security/Guard/AbstractGuardAuthenticator.php b/src/Symfony/Component/Security/Guard/AbstractGuardAuthenticator.php index ebd09bb73f..647cb0250c 100644 --- a/src/Symfony/Component/Security/Guard/AbstractGuardAuthenticator.php +++ b/src/Symfony/Component/Security/Guard/AbstractGuardAuthenticator.php @@ -3,26 +3,26 @@ namespace Symfony\Component\Security\Guard; use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Guard\Token\GenericGuardToken; +use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; /** - * An optional base class that creates a GenericGuardToken for you + * An optional base class that creates a PostAuthenticationGuardToken for you * * @author Ryan Weaver */ abstract class AbstractGuardAuthenticator implements GuardAuthenticatorInterface { /** - * Shortcut to create a GenericGuardToken for you, if you don't really + * Shortcut to create a PostAuthenticationGuardToken for you, if you don't really * care about which authenticated token you're using * * @param UserInterface $user * @param string $providerKey - * @return GenericGuardToken + * @return PostAuthenticationGuardToken */ public function createAuthenticatedToken(UserInterface $user, $providerKey) { - return new GenericGuardToken( + return new PostAuthenticationGuardToken( $user, $providerKey, $user->getRoles() diff --git a/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php b/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php index a53478a2b7..6a4f09cfbd 100644 --- a/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php +++ b/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php @@ -6,7 +6,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; -use Symfony\Component\Security\Guard\Token\NonAuthenticatedGuardToken; +use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Guard\GuardAuthenticatorInterface; use Psr\Log\LoggerInterface; @@ -86,7 +86,7 @@ class GuardAuthenticationListener implements ListenerInterface } // create a token with the unique key, so that the provider knows which authenticator to use - $token = new NonAuthenticatedGuardToken($credentials, $uniqueGuardKey); + $token = new PreAuthenticationGuardToken($credentials, $uniqueGuardKey); if (null !== $this->logger) { $this->logger->info('Passing guard token information to the GuardAuthenticationProvider', array('firewall_key' => $this->providerKey, 'authenticator' => get_class($guardAuthenticator))); diff --git a/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php b/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php index 740f4c47c2..150943dffa 100644 --- a/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php +++ b/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php @@ -3,15 +3,18 @@ namespace Symfony\Component\Security\Guard\Provider; use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; +use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; +use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Guard\GuardAuthenticatorInterface; -use Symfony\Component\Security\Guard\Token\NonAuthenticatedGuardToken; +use Symfony\Component\Security\Guard\Token\GuardTokenInterface; +use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; 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; /** - * Responsible for accepting the NonAuthenticatedGuardToken and calling + * Responsible for accepting the PreAuthenticationGuardToken and calling * the correct authenticator to retrieve the authenticated token * * @author Ryan Weaver @@ -43,12 +46,12 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface /** * Finds the correct authenticator for the token and calls it * - * @param NonAuthenticatedGuardToken $token + * @param GuardTokenInterface $token * @return TokenInterface */ public function authenticate(TokenInterface $token) { - if (!$token instanceof NonAuthenticatedGuardToken) { + if (!$this->supports($token)) { throw new \InvalidArgumentException('GuardAuthenticationProvider only supports NonAuthenticatedGuardToken'); } @@ -69,7 +72,7 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface )); } - private function authenticateViaGuard(GuardAuthenticatorInterface $guardAuthenticator, NonAuthenticatedGuardToken $token) + private function authenticateViaGuard(GuardAuthenticatorInterface $guardAuthenticator, PreAuthenticationGuardToken $token) { // get the user from the GuardAuthenticator $user = $guardAuthenticator->authenticate($token->getCredentials(), $this->userProvider); @@ -101,6 +104,6 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface public function supports(TokenInterface $token) { - return $token instanceof NonAuthenticatedGuardToken; + return $token instanceof GuardTokenInterface; } } diff --git a/src/Symfony/Component/Security/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php b/src/Symfony/Component/Security/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php index b8939a93dd..2de60c1100 100644 --- a/src/Symfony/Component/Security/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php +++ b/src/Symfony/Component/Security/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php @@ -14,7 +14,7 @@ namespace Symfony\Component\Security\Guard\Tests\Firewall; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Guard\Firewall\GuardAuthenticationListener; -use Symfony\Component\Security\Guard\Token\NonAuthenticatedGuardToken; +use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; use Symfony\Component\Security\Core\Exception\AuthenticationException; /** @@ -44,7 +44,7 @@ class GuardAuthenticationListenerTest extends \PHPUnit_Framework_TestCase // a clone of the token that should be created internally $uniqueGuardKey = 'my_firewall_0'; - $nonAuthedToken = new NonAuthenticatedGuardToken($credentials, $uniqueGuardKey); + $nonAuthedToken = new PreAuthenticationGuardToken($credentials, $uniqueGuardKey); $this->authenticationManager ->expects($this->once()) diff --git a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php index 0ef6818659..7df3ecb9d6 100644 --- a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php +++ b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php @@ -20,7 +20,7 @@ class GuardAuthenticationProviderTest extends \PHPUnit_Framework_TestCase { private $userProvider; private $userChecker; - private $nonAuthedToken; + private $preAuthenticationToken; public function testAuthenticate() { @@ -32,7 +32,7 @@ class GuardAuthenticationProviderTest extends \PHPUnit_Framework_TestCase $authenticators = array($authenticatorA, $authenticatorB, $authenticatorC); // called 2 times - for authenticator A and B (stops on B because of match) - $this->nonAuthedToken->expects($this->exactly(2)) + $this->preAuthenticationToken->expects($this->exactly(2)) ->method('getGuardProviderKey') // it will return the "1" index, which will match authenticatorB ->will($this->returnValue('my_cool_firewall_1')); @@ -41,7 +41,7 @@ class GuardAuthenticationProviderTest extends \PHPUnit_Framework_TestCase 'username' => '_weaverryan_test_user', 'password' => 'guard_auth_ftw', ); - $this->nonAuthedToken->expects($this->once()) + $this->preAuthenticationToken->expects($this->once()) ->method('getCredentials') ->will($this->returnValue($enteredCredentials)); @@ -71,7 +71,7 @@ class GuardAuthenticationProviderTest extends \PHPUnit_Framework_TestCase ->with($mockedUser); $provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, $providerKey, $this->userChecker); - $actualAuthedToken = $provider->authenticate($this->nonAuthedToken); + $actualAuthedToken = $provider->authenticate($this->preAuthenticationToken); $this->assertSame($authedToken, $actualAuthedToken); } @@ -79,7 +79,7 @@ class GuardAuthenticationProviderTest extends \PHPUnit_Framework_TestCase { $this->userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface'); $this->userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface'); - $this->nonAuthedToken = $this->getMockBuilder('Symfony\Component\Security\Guard\Token\NonAuthenticatedGuardToken') + $this->preAuthenticationToken = $this->getMockBuilder('Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken') ->disableOriginalConstructor() ->getMock(); } @@ -88,6 +88,6 @@ class GuardAuthenticationProviderTest extends \PHPUnit_Framework_TestCase { $this->userProvider = null; $this->userChecker = null; - $this->nonAuthedToken = null; + $this->preAuthenticationToken = null; } } diff --git a/src/Symfony/Component/Security/Guard/Token/GuardTokenInterface.php b/src/Symfony/Component/Security/Guard/Token/GuardTokenInterface.php new file mode 100644 index 0000000000..f4afb70a5d --- /dev/null +++ b/src/Symfony/Component/Security/Guard/Token/GuardTokenInterface.php @@ -0,0 +1,15 @@ + + */ +interface GuardTokenInterface +{ +} diff --git a/src/Symfony/Component/Security/Guard/Token/GenericGuardToken.php b/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php similarity index 87% rename from src/Symfony/Component/Security/Guard/Token/GenericGuardToken.php rename to src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php index 869d0710c8..5b7e20e3b7 100644 --- a/src/Symfony/Component/Security/Guard/Token/GenericGuardToken.php +++ b/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php @@ -7,17 +7,14 @@ use Symfony\Component\Security\Core\Role\RoleInterface; use Symfony\Component\Security\Core\User\UserInterface; /** - * A generic token used by the AbstractGuardAuthenticator + * Used as an "authenticated" token, though it could be set to not-authenticated later. * - * This is meant to be used as an "authenticated" token, though it - * could be set to not-authenticated later. - * - * You're free to use this (it's simple) or use any other token for - * your authenticated token + * If you're using Guard authentication, you *must* use a class that implements + * GuardTokenInterface as your authenticated token (like this class). * * @author Ryan Weaver */ -class GenericGuardToken extends AbstractToken +class PostAuthenticationGuardToken extends AbstractToken implements GuardTokenInterface { private $providerKey; diff --git a/src/Symfony/Component/Security/Guard/Token/NonAuthenticatedGuardToken.php b/src/Symfony/Component/Security/Guard/Token/PreAuthenticationGuardToken.php similarity index 88% rename from src/Symfony/Component/Security/Guard/Token/NonAuthenticatedGuardToken.php rename to src/Symfony/Component/Security/Guard/Token/PreAuthenticationGuardToken.php index 28e21e0dee..1bfe6395b9 100644 --- a/src/Symfony/Component/Security/Guard/Token/NonAuthenticatedGuardToken.php +++ b/src/Symfony/Component/Security/Guard/Token/PreAuthenticationGuardToken.php @@ -13,7 +13,7 @@ use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; * * @author Ryan Weaver */ -class NonAuthenticatedGuardToken extends AbstractToken +class PreAuthenticationGuardToken extends AbstractToken implements GuardTokenInterface { private $credentials; private $guardProviderKey; @@ -51,6 +51,6 @@ class NonAuthenticatedGuardToken extends AbstractToken public function setAuthenticated($authenticated) { - throw new \Exception('The NonAuthenticatedGuardToken is *always* not authenticated'); + throw new \Exception('The PreAuthenticationGuardToken is *always* not authenticated'); } }