diff options
-rw-r--r-- | Authentication/AuthenticationTrustResolver.php | 66 | ||||
-rw-r--r-- | Authentication/AuthenticationTrustResolverInterface.php | 53 | ||||
-rw-r--r-- | Authentication/Token/RememberMeToken.php | 56 | ||||
-rw-r--r-- | Authorization/Voter/AuthenticatedVoter.php | 40 |
4 files changed, 209 insertions, 6 deletions
diff --git a/Authentication/AuthenticationTrustResolver.php b/Authentication/AuthenticationTrustResolver.php new file mode 100644 index 0000000..010fa91 --- /dev/null +++ b/Authentication/AuthenticationTrustResolver.php @@ -0,0 +1,66 @@ +<?php + +namespace Symfony\Component\Security\Authentication; + +use Symfony\Component\Security\Authentication\Token\TokenInterface; + +/** + * The default implementation of the authentication trust resolver. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class AuthenticationTrustResolver implements AuthenticationTrustResolverInterface +{ + protected $anonymousClass; + protected $rememberMeClass; + + /** + * Constructor + * + * @param string $anonymousClass + * @param string $rememberMeClass + * + * @return void + */ + public function __construct($anonymousClass, $rememberMeClass) + { + $this->anonymousClass = $anonymousClass; + $this->rememberMeClass = $rememberMeClass; + } + + /** + * {@inheritDoc} + */ + public function isAnonymous(TokenInterface $token = null) + { + if (null === $token) { + return false; + } + + return $token instanceof $this->anonymousClass; + } + + /** + * {@inheritDoc} + */ + public function isRememberMe(TokenInterface $token = null) + { + if (null === $token) { + return false; + } + + return $token instanceof $this->rememberMeClass; + } + + /** + * {@inheritDoc} + */ + public function isFullFledged(TokenInterface $token = null) + { + if (null === $token) { + return false; + } + + return !$this->isAnonymous($token) && !$this->isRememberMe($token); + } +} diff --git a/Authentication/AuthenticationTrustResolverInterface.php b/Authentication/AuthenticationTrustResolverInterface.php new file mode 100644 index 0000000..e57bb65 --- /dev/null +++ b/Authentication/AuthenticationTrustResolverInterface.php @@ -0,0 +1,53 @@ +<?php + +namespace Symfony\Component\Security\Authentication; + +use Symfony\Component\Security\Authentication\Token\TokenInterface; + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien.potencier@symfony-project.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Interface for resolving the authentication status of a given token. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +interface AuthenticationTrustResolverInterface +{ + /** + * Resolves whether the passed token implementation is authenticated + * anonymously. + * + * If null is passed, the method must return false. + * + * @param TokenInterface $token + * + * @return Boolean + */ + function isAnonymous(TokenInterface $token = null); + + /** + * Resolves whether the passed token implementation is authenticated + * using remember-me capabilities. + * + * @param TokenInterface $token + * + * @return Boolean + */ + function isRememberMe(TokenInterface $token = null); + + /** + * Resolves whether the passed token implementation is fully authenticated. + * + * @param TokenInterface $token + * + * @return Boolean + */ + function isFullFledged(TokenInterface $token = null); +} diff --git a/Authentication/Token/RememberMeToken.php b/Authentication/Token/RememberMeToken.php new file mode 100644 index 0000000..587222d --- /dev/null +++ b/Authentication/Token/RememberMeToken.php @@ -0,0 +1,56 @@ +<?php + +namespace Symfony\Component\Security\Authentication\Token; + +use Symfony\Component\Security\Authentication\RememberMe\PersistentTokenInterface; +use Symfony\Component\Security\User\AccountInterface; + +/** + * Base class for "Remember Me" tokens + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class RememberMeToken extends Token +{ + protected $key; + + /** + * The persistent token which resulted in this authentication token. + * + * @var PersistentTokenInterface + */ + protected $persistentToken; + + /** + * Constructor. + * + * @param string $username + * @param string $key + */ + public function __construct(AccountInterface $user, $key) { + parent::__construct($user->getRoles()); + + if (0 === strlen($key)) { + throw new \InvalidArgumentException('$key cannot be empty.'); + } + + $this->user = $user; + $this->key = $key; + $this->setAuthenticated(true); + } + + public function getKey() + { + return $this->key; + } + + public function setPersistentToken(PersistentTokenInterface $persistentToken) + { + $this->persistentToken = $persistentToken; + } + + public function getPersistentToken() + { + return $this->persistentToken; + } +} diff --git a/Authorization/Voter/AuthenticatedVoter.php b/Authorization/Voter/AuthenticatedVoter.php index 4b330f9..bf78626 100644 --- a/Authorization/Voter/AuthenticatedVoter.php +++ b/Authorization/Voter/AuthenticatedVoter.php @@ -2,8 +2,8 @@ namespace Symfony\Component\Security\Authorization\Voter; +use Symfony\Component\Security\Authentication\AuthenticationTrustResolverInterface; use Symfony\Component\Security\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Authentication\Token\AnonymousToken; /* * This file is part of the Symfony package. @@ -15,22 +15,40 @@ use Symfony\Component\Security\Authentication\Token\AnonymousToken; */ /** - * AuthenticatedVoter votes if an attribute like IS_AUTHENTICATED_FULLY or - * IS_AUTHENTICATED_ANONYMOUSLY is present. + * AuthenticatedVoter votes if an attribute like IS_AUTHENTICATED_FULLY, + * IS_AUTHENTICATED_REMEMBERED, or IS_AUTHENTICATED_ANONYMOUSLY is present. + * + * This list is most restrictive to least restrictive checking. * * @author Fabien Potencier <fabien.potencier@symfony-project.com> + * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ class AuthenticatedVoter implements VoterInterface { const IS_AUTHENTICATED_FULLY = 'IS_AUTHENTICATED_FULLY'; + const IS_AUTHENTICATED_REMEMBERED = 'IS_AUTHENTICATED_REMEMBERED'; const IS_AUTHENTICATED_ANONYMOUSLY = 'IS_AUTHENTICATED_ANONYMOUSLY'; + protected $authenticationTrustResolver; + + /** + * Constructor. + * + * @param AuthenticationTrustResolverInterface $authenticationTrustResolver + * + * @return void + */ + public function __construct(AuthenticationTrustResolverInterface $authenticationTrustResolver) + { + $this->authenticationTrustResolver = $authenticationTrustResolver; + } + /** * {@inheritdoc} */ public function supportsAttribute($attribute) { - return null !== $attribute && (self::IS_AUTHENTICATED_FULLY === $attribute || self::IS_AUTHENTICATED_ANONYMOUSLY === $attribute); + return null !== $attribute && (self::IS_AUTHENTICATED_FULLY === $attribute || self::IS_AUTHENTICATED_REMEMBERED === $attribute || self::IS_AUTHENTICATED_ANONYMOUSLY === $attribute); } /** @@ -54,11 +72,21 @@ class AuthenticatedVoter implements VoterInterface $result = VoterInterface::ACCESS_DENIED; - if (self::IS_AUTHENTICATED_FULLY === $attribute && !$token instanceof AnonymousToken) { + if (self::IS_AUTHENTICATED_FULLY === $attribute + && $this->authenticationTrustResolver->isFullFledged($token)) { + return VoterInterface::ACCESS_GRANTED; + } + + if (self::IS_AUTHENTICATED_REMEMBERED === $attribute + && ($this->authenticationTrustResolver->isRememberMe($token) + || $this->authenticationTrustResolver->isFullFledged($token))) { return VoterInterface::ACCESS_GRANTED; } - if (self::IS_AUTHENTICATED_ANONYMOUSLY === $attribute) { + if (self::IS_AUTHENTICATED_ANONYMOUSLY === $attribute + && ($this->authenticationTrustResolver->isAnonymous($token) + || $this->authenticationTrustResolver->isRememberMe($token) + || $this->authenticationTrustResolver->isFullFledged($token))) { return VoterInterface::ACCESS_GRANTED; } } |