summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Schmitt <schmittjoh@gmail.com>2011-01-25 20:28:26 +0100
committerFabien Potencier <fabien.potencier@gmail.com>2011-01-26 16:38:54 +0100
commit521c9f65e9d70618f63ac6ed803a495651b9fd35 (patch)
tree4e64bf3f877a4050eb3eb95c0b55630a4105053c
parentbff922f5c7ab61fb144e124b584da067842cb955 (diff)
downloadsymfony-security-521c9f65e9d70618f63ac6ed803a495651b9fd35.zip
symfony-security-521c9f65e9d70618f63ac6ed803a495651b9fd35.tar.gz
symfony-security-521c9f65e9d70618f63ac6ed803a495651b9fd35.tar.bz2
[Security] many improvements, and fixes
-rw-r--r--Acl/Domain/SecurityIdentityRetrievalStrategy.php11
-rw-r--r--Acl/Domain/UserSecurityIdentity.php20
-rw-r--r--Authentication/Provider/DaoAuthenticationProvider.php5
-rw-r--r--Authentication/Provider/PreAuthenticatedAuthenticationProvider.php7
-rw-r--r--Authentication/Provider/RememberMeAuthenticationProvider.php45
-rw-r--r--Authentication/Provider/UserAuthenticationProvider.php12
-rw-r--r--Authentication/RememberMe/InMemoryTokenProvider.php50
-rw-r--r--Authentication/RememberMe/PersistentToken.php107
-rw-r--r--Authentication/RememberMe/PersistentTokenInterface.php45
-rw-r--r--Authentication/RememberMe/TokenProviderInterface.php51
-rw-r--r--Authentication/Token/PreAuthenticatedToken.php10
-rw-r--r--Authentication/Token/RememberMeToken.php28
-rw-r--r--Authentication/Token/UsernamePasswordToken.php13
-rw-r--r--Exception/CookieTheftException.php22
-rw-r--r--Exception/TokenNotFoundException.php20
-rw-r--r--SecurityContext.php15
-rw-r--r--User/InMemoryUserProvider.php8
-rw-r--r--User/User.php1
-rw-r--r--User/UserProviderInterface.php15
19 files changed, 456 insertions, 29 deletions
diff --git a/Acl/Domain/SecurityIdentityRetrievalStrategy.php b/Acl/Domain/SecurityIdentityRetrievalStrategy.php
index eaf48de..d347b97 100644
--- a/Acl/Domain/SecurityIdentityRetrievalStrategy.php
+++ b/Acl/Domain/SecurityIdentityRetrievalStrategy.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Acl\Domain;
+use Symfony\Component\Security\Authentication\Token\AnonymousToken;
+
use Symfony\Component\Security\User\AccountInterface;
use Symfony\Component\Security\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface;
@@ -49,9 +51,12 @@ class SecurityIdentityRetrievalStrategy implements SecurityIdentityRetrievalStra
$sids = array();
// add user security identity
- $user = $token->getUser();
- if ($user instanceof AccountInterface) {
- $sids[] = UserSecurityIdentity::fromAccount($user);
+ if (!$token instanceof AnonymousToken) {
+ try {
+ $sids[] = UserSecurityIdentity::fromToken($token);
+ } catch (\InvalidArgumentException $invalid) {
+ // ignore, user has no user security identity
+ }
}
// add all reachable roles
diff --git a/Acl/Domain/UserSecurityIdentity.php b/Acl/Domain/UserSecurityIdentity.php
index 3b03191..3c30a96 100644
--- a/Acl/Domain/UserSecurityIdentity.php
+++ b/Acl/Domain/UserSecurityIdentity.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Security\Acl\Domain;
+use Symfony\Component\Security\Authentication\Token\TokenInterface;
use Symfony\Component\Security\User\AccountInterface;
use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface;
@@ -51,7 +52,24 @@ class UserSecurityIdentity implements SecurityIdentityInterface
*/
public static function fromAccount(AccountInterface $user)
{
- return new self((string) $user, get_class($user));
+ return new self($user->getUsername(), get_class($user));
+ }
+
+ /**
+ * Creates a user security identity from a TokenInterface
+ *
+ * @param TokenInterface $token
+ * @return UserSecurityIdentity
+ */
+ public static function fromToken(TokenInterface $token)
+ {
+ $user = $token->getUser();
+
+ if ($user instanceof AccountInterface) {
+ return self::fromAccount($user);
+ }
+
+ return new self((string) $user, is_object($user)? get_class($user) : get_class($token));
}
/**
diff --git a/Authentication/Provider/DaoAuthenticationProvider.php b/Authentication/Provider/DaoAuthenticationProvider.php
index d83a125..69ef9a3 100644
--- a/Authentication/Provider/DaoAuthenticationProvider.php
+++ b/Authentication/Provider/DaoAuthenticationProvider.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Security\Authentication\Provider;
+use Symfony\Component\Security\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Encoder\EncoderFactoryInterface;
use Symfony\Component\Security\User\UserProviderInterface;
use Symfony\Component\Security\User\AccountCheckerInterface;
@@ -38,9 +39,9 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider
* @param AccountCheckerInterface $accountChecker An AccountCheckerInterface instance
* @param EncoderFactoryInterface $encoderFactory A EncoderFactoryInterface instance
*/
- public function __construct(UserProviderInterface $userProvider, AccountCheckerInterface $accountChecker, EncoderFactoryInterface $encoderFactory, $hideUserNotFoundExceptions = true)
+ public function __construct(UserProviderInterface $userProvider, AccountCheckerInterface $accountChecker, $providerKey, EncoderFactoryInterface $encoderFactory, $hideUserNotFoundExceptions = true)
{
- parent::__construct($accountChecker, $hideUserNotFoundExceptions);
+ parent::__construct($accountChecker, $providerKey, $hideUserNotFoundExceptions);
$this->encoderFactory = $encoderFactory;
$this->userProvider = $userProvider;
diff --git a/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php b/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php
index aab823a..850b1ec 100644
--- a/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php
+++ b/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Security\Authentication\Provider;
+use Symfony\Component\Security\User\AccountInterface;
use Symfony\Component\Security\User\UserProviderInterface;
use Symfony\Component\Security\User\AccountCheckerInterface;
use Symfony\Component\Security\Exception\BadCredentialsException;
@@ -31,6 +32,7 @@ class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderIn
{
protected $userProvider;
protected $accountChecker;
+ protected $providerKey;
/**
* Constructor.
@@ -38,10 +40,11 @@ class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderIn
* @param UserProviderInterface $userProvider A UserProviderInterface instance
* @param AccountCheckerInterface $accountChecker An AccountCheckerInterface instance
*/
- public function __construct(UserProviderInterface $userProvider, AccountCheckerInterface $accountChecker)
+ public function __construct(UserProviderInterface $userProvider, AccountCheckerInterface $accountChecker, $providerKey)
{
$this->userProvider = $userProvider;
$this->accountChecker = $accountChecker;
+ $this->providerKey = $providerKey;
}
/**
@@ -73,6 +76,6 @@ class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderIn
*/
public function supports(TokenInterface $token)
{
- return $token instanceof PreAuthenticatedToken;
+ return $token instanceof PreAuthenticatedToken && $this->providerKey === $token->getProviderKey();
}
}
diff --git a/Authentication/Provider/RememberMeAuthenticationProvider.php b/Authentication/Provider/RememberMeAuthenticationProvider.php
new file mode 100644
index 0000000..d2d0268
--- /dev/null
+++ b/Authentication/Provider/RememberMeAuthenticationProvider.php
@@ -0,0 +1,45 @@
+<?php
+namespace Symfony\Component\Security\Authentication\Provider;
+
+use Symfony\Component\Security\User\AccountCheckerInterface;
+use Symfony\Component\Security\User\AccountInterface;
+use Symfony\Component\Security\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Authentication\Token\RememberMeToken;
+use Symfony\Component\Security\Exception\BadCredentialsException;
+
+class RememberMeAuthenticationProvider implements AuthenticationProviderInterface
+{
+ protected $accountChecker;
+ protected $key;
+ protected $providerKey;
+
+ public function __construct(AccountCheckerInterface $accountChecker, $key, $providerKey)
+ {
+ $this->accountChecker = $accountChecker;
+ $this->key = $key;
+ $this->providerKey = $providerKey;
+ }
+
+ public function authenticate(TokenInterface $token)
+ {
+ if (!$this->supports($token)) {
+ return;
+ }
+
+ if ($this->key !== $token->getKey()) {
+ throw new BadCredentialsException('The presented key does not match.');
+ }
+
+ $user = $token->getUser();
+ $this->accountChecker->checkPreAuth($user);
+ $this->accountChecker->checkPostAuth($user);
+ $token->setAuthenticated(true);
+
+ return $token;
+ }
+
+ public function supports(TokenInterface $token)
+ {
+ return $token instanceof RememberMeToken && $token->getProviderKey() === $this->providerKey;
+ }
+} \ No newline at end of file
diff --git a/Authentication/Provider/UserAuthenticationProvider.php b/Authentication/Provider/UserAuthenticationProvider.php
index 9ee4d61..fa678b7 100644
--- a/Authentication/Provider/UserAuthenticationProvider.php
+++ b/Authentication/Provider/UserAuthenticationProvider.php
@@ -29,6 +29,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
{
protected $hideUserNotFoundExceptions;
protected $accountChecker;
+ protected $providerKey;
/**
* Constructor.
@@ -36,9 +37,14 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
* @param AccountCheckerInterface $accountChecker An AccountCheckerInterface interface
* @param Boolean $hideUserNotFoundExceptions Whether to hide user not found exception or not
*/
- public function __construct(AccountCheckerInterface $accountChecker, $hideUserNotFoundExceptions = true)
+ public function __construct(AccountCheckerInterface $accountChecker, $providerKey, $hideUserNotFoundExceptions = true)
{
+ if (empty($providerKey)) {
+ throw new \InvalidArgumentException('$providerKey must not be empty.');
+ }
+
$this->accountChecker = $accountChecker;
+ $this->providerKey = $providerKey;
$this->hideUserNotFoundExceptions = $hideUserNotFoundExceptions;
}
@@ -64,7 +70,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
$this->checkAuthentication($user, $token);
$this->accountChecker->checkPostAuth($user);
- return new UsernamePasswordToken($user, $token->getCredentials(), $user->getRoles());
+ return new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles());
} catch (UsernameNotFoundException $notFound) {
if ($this->hideUserNotFoundExceptions) {
throw new BadCredentialsException('Bad credentials', 0, $notFound);
@@ -79,7 +85,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
*/
public function supports(TokenInterface $token)
{
- return $token instanceof UsernamePasswordToken;
+ return $token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey();
}
/**
diff --git a/Authentication/RememberMe/InMemoryTokenProvider.php b/Authentication/RememberMe/InMemoryTokenProvider.php
new file mode 100644
index 0000000..71c1bf2
--- /dev/null
+++ b/Authentication/RememberMe/InMemoryTokenProvider.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\RememberMe;
+
+use Symfony\Component\Security\Exception\TokenNotFoundException;
+
+/**
+ * This class is used for testing purposes, and is not really suited for production.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class InMemoryTokenProvider implements TokenProviderInterface
+{
+ protected $tokens = array();
+
+ public function loadTokenBySeries($series)
+ {
+ if (!isset($this->tokens[$series])) {
+ throw new TokenNotFoundException('No token found.');
+ }
+
+ return $this->tokens[$series];
+ }
+
+ public function updateToken($series, $tokenValue, \DateTime $lastUsed)
+ {
+ if (!isset($this->tokens[$series])) {
+ throw new TokenNotFoundException('No token found.');
+ }
+
+ $token = new PersistentToken(
+ $this->tokens[$series]->getClass(),
+ $this->tokens[$series]->getUsername(),
+ $series,
+ $tokenValue,
+ $lastUsed
+ );
+ $this->tokens[$series] = $token;
+ }
+
+ public function deleteTokenBySeries($series)
+ {
+ unset($this->tokens[$series]);
+ }
+
+ public function createNewToken(PersistentTokenInterface $token)
+ {
+ $this->tokens[$token->getSeries()] = $token;
+ }
+} \ No newline at end of file
diff --git a/Authentication/RememberMe/PersistentToken.php b/Authentication/RememberMe/PersistentToken.php
new file mode 100644
index 0000000..cdbc296
--- /dev/null
+++ b/Authentication/RememberMe/PersistentToken.php
@@ -0,0 +1,107 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\RememberMe;
+
+/*
+ * 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.
+ */
+
+/**
+ * This class is only used by PersistentTokenRememberMeServices internally.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+final class PersistentToken implements PersistentTokenInterface
+{
+ private $class;
+ private $username;
+ private $series;
+ private $tokenValue;
+ private $lastUsed;
+
+ /**
+ * Constructor
+ *
+ * @param string $class
+ * @param string $username
+ * @param string $series
+ * @param string $tokenValue
+ * @param DateTime $lastUsed
+ */
+ public function __construct($class, $username, $series, $tokenValue, \DateTime $lastUsed)
+ {
+ if (empty($class)) {
+ throw new \InvalidArgumentException('$class must not be empty.');
+ }
+ if (empty($username)) {
+ throw new \InvalidArgumentException('$username must not be empty.');
+ }
+ if (empty($series)) {
+ throw new \InvalidArgumentException('$series must not be empty.');
+ }
+ if (empty($tokenValue)) {
+ throw new \InvalidArgumentException('$tokenValue must not be empty.');
+ }
+
+ $this->class = $class;
+ $this->username = $username;
+ $this->series = $series;
+ $this->tokenValue = $tokenValue;
+ $this->lastUsed = $lastUsed;
+ }
+
+ /**
+ * Returns the class of the user
+ *
+ * @return string
+ */
+ public function getClass()
+ {
+ return $this->class;
+ }
+
+ /**
+ * Returns the username
+ *
+ * @return string
+ */
+ public function getUsername()
+ {
+ return $this->username;
+ }
+
+ /**
+ * Returns the series
+ *
+ * @return string
+ */
+ public function getSeries()
+ {
+ return $this->series;
+ }
+
+ /**
+ * Returns the token value
+ *
+ * @return string
+ */
+ public function getTokenValue()
+ {
+ return $this->tokenValue;
+ }
+
+ /**
+ * Returns the time the token was last used
+ *
+ * @return DateTime
+ */
+ public function getLastUsed()
+ {
+ return $this->lastUsed;
+ }
+} \ No newline at end of file
diff --git a/Authentication/RememberMe/PersistentTokenInterface.php b/Authentication/RememberMe/PersistentTokenInterface.php
new file mode 100644
index 0000000..5525a34
--- /dev/null
+++ b/Authentication/RememberMe/PersistentTokenInterface.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\RememberMe;
+
+/*
+ * 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 to be implemented by persistent token classes (such as
+ * Doctrine entities representing a remember-me token)
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface PersistentTokenInterface
+{
+ /**
+ * Returns the username
+ * @return string
+ */
+ function getUsername();
+
+ /**
+ * Returns the series
+ * @return string
+ */
+ function getSeries();
+
+ /**
+ * Returns the token value
+ * @return string
+ */
+ function getTokenValue();
+
+ /**
+ * Returns the last time the cookie was used
+ * @return \DateTime
+ */
+ function getLastUsed();
+} \ No newline at end of file
diff --git a/Authentication/RememberMe/TokenProviderInterface.php b/Authentication/RememberMe/TokenProviderInterface.php
new file mode 100644
index 0000000..0ed3f50
--- /dev/null
+++ b/Authentication/RememberMe/TokenProviderInterface.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\RememberMe;
+
+/*
+ * 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 TokenProviders
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface TokenProviderInterface
+{
+ /**
+ * Loads the active token for the given series
+ *
+ * @throws TokenNotFoundException if the token is not found
+ *
+ * @param string $series
+ * @return PersistentTokenInterface
+ */
+ function loadTokenBySeries($series);
+
+ /**
+ * Deletes all tokens belonging to series
+ * @param string $series
+ */
+ function deleteTokenBySeries($series);
+
+ /**
+ * Updates the token according to this data
+ *
+ * @param string $series
+ * @param string $tokenValue
+ * @param DateTime $lastUsed
+ */
+ function updateToken($series, $tokenValue, \DateTime $lastUsed);
+
+ /**
+ * Creates a new token
+ * @param PersistentTokenInterface $token
+ */
+ function createNewToken(PersistentTokenInterface $token);
+} \ No newline at end of file
diff --git a/Authentication/Token/PreAuthenticatedToken.php b/Authentication/Token/PreAuthenticatedToken.php
index 8c6fc5f..0980ae6 100644
--- a/Authentication/Token/PreAuthenticatedToken.php
+++ b/Authentication/Token/PreAuthenticatedToken.php
@@ -18,10 +18,12 @@ namespace Symfony\Component\Security\Authentication\Token;
*/
class PreAuthenticatedToken extends Token
{
+ protected $providerKey;
+
/**
* Constructor.
*/
- public function __construct($user, $credentials, array $roles = null)
+ public function __construct($user, $credentials, $providerKey, array $roles = null)
{
parent::__construct(null === $roles ? array() : $roles);
if (null !== $roles) {
@@ -30,6 +32,12 @@ class PreAuthenticatedToken extends Token
$this->user = $user;
$this->credentials = $credentials;
+ $this->providerKey = $providerKey;
+ }
+
+ public function getProviderKey()
+ {
+ return $this->providerKey;
}
/**
diff --git a/Authentication/Token/RememberMeToken.php b/Authentication/Token/RememberMeToken.php
index 50284aa..f006a3a 100644
--- a/Authentication/Token/RememberMeToken.php
+++ b/Authentication/Token/RememberMeToken.php
@@ -22,6 +22,7 @@ use Symfony\Component\Security\User\AccountInterface;
class RememberMeToken extends Token
{
protected $key;
+ protected $providerKey;
/**
* The persistent token which resulted in this authentication token.
@@ -36,30 +37,39 @@ class RememberMeToken extends Token
* @param string $username
* @param string $key
*/
- public function __construct(AccountInterface $user, $key) {
+ public function __construct(AccountInterface $user, $providerKey, $key) {
parent::__construct($user->getRoles());
- if (0 === strlen($key)) {
- throw new \InvalidArgumentException('$key cannot be empty.');
+ if (empty($key)) {
+ throw new \InvalidArgumentException('$key must not be empty.');
+ }
+ if (empty($providerKey)) {
+ throw new \InvalidArgumentException('$providerKey must not be empty.');
}
- $this->user = $user;
+ $this->setUser($user);
+ $this->providerKey = $providerKey;
$this->key = $key;
$this->setAuthenticated(true);
}
- public function getKey()
+ public function getProviderKey()
{
- return $this->key;
+ return $this->providerKey;
}
- public function setPersistentToken(PersistentTokenInterface $persistentToken)
+ public function getKey()
{
- $this->persistentToken = $persistentToken;
+ return $this->key;
}
public function getPersistentToken()
{
return $this->persistentToken;
}
-}
+
+ public function setPersistentToken(PersistentTokenInterface $persistentToken)
+ {
+ $this->persistentToken = $persistentToken;
+ }
+} \ No newline at end of file
diff --git a/Authentication/Token/UsernamePasswordToken.php b/Authentication/Token/UsernamePasswordToken.php
index ed82ec8..1794481 100644
--- a/Authentication/Token/UsernamePasswordToken.php
+++ b/Authentication/Token/UsernamePasswordToken.php
@@ -18,19 +18,30 @@ namespace Symfony\Component\Security\Authentication\Token;
*/
class UsernamePasswordToken extends Token
{
+ protected $providerKey;
+
/**
* Constructor.
+ *
+ * @param string $user The username (like a nickname, email address, etc.)
+ * @param string $credentials This usually is the password of the user
*/
- public function __construct($user, $credentials, array $roles = array())
+ public function __construct($user, $credentials, $providerKey, array $roles = array())
{
parent::__construct($roles);
$this->setUser($user);
$this->credentials = $credentials;
+ $this->providerKey = $providerKey;
parent::setAuthenticated((Boolean) count($roles));
}
+ public function getProviderKey()
+ {
+ return $this->providerKey;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/Exception/CookieTheftException.php b/Exception/CookieTheftException.php
new file mode 100644
index 0000000..a69ccdf
--- /dev/null
+++ b/Exception/CookieTheftException.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Symfony\Component\Security\Exception;
+
+/*
+ * 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.
+ */
+
+/**
+ * This exception is thrown when the RememberMeServices implementation
+ * detects that a presented cookie has already been used by someone else.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class CookieTheftException extends AuthenticationException
+{
+} \ No newline at end of file
diff --git a/Exception/TokenNotFoundException.php b/Exception/TokenNotFoundException.php
new file mode 100644
index 0000000..65d2d2a
--- /dev/null
+++ b/Exception/TokenNotFoundException.php
@@ -0,0 +1,20 @@
+<?php
+namespace Symfony\Component\Security\Exception;
+
+/*
+ * 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.
+ */
+
+/**
+ * TokenNotFoundException is thrown if a Token cannot be found.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class TokenNotFoundException extends AuthenticationException
+{
+}
diff --git a/SecurityContext.php b/SecurityContext.php
index e694d82..bf6324a 100644
--- a/SecurityContext.php
+++ b/SecurityContext.php
@@ -11,8 +11,9 @@
namespace Symfony\Component\Security;
+use Symfony\Component\Security\Authorization\AccessDecisionManagerInterface;
+use Symfony\Component\Security\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Authentication\Token\TokenInterface;
-use Symfony\Component\Security\Authorization\AccessDecisionManager;
use Symfony\Component\Security\Acl\Voter\FieldVote;
/**
@@ -30,15 +31,19 @@ class SecurityContext
protected $token;
protected $accessDecisionManager;
+ protected $authenticationManager;
+ protected $alwaysAuthenticate;
/**
* Constructor.
*
- * @param AccessDecisionManager|null $accessDecisionManager An AccessDecisionManager instance
+ * @param AccessDecisionManagerInterface|null $accessDecisionManager An AccessDecisionManager instance
*/
- public function __construct(AccessDecisionManager $accessDecisionManager = null)
+ public function __construct(AuthenticationManagerInterface $authenticationManager, AccessDecisionManagerInterface $accessDecisionManager = null, $alwaysAuthenticate = false)
{
+ $this->authenticationManager = $authenticationManager;
$this->accessDecisionManager = $accessDecisionManager;
+ $this->alwaysAuthenticate = $alwaysAuthenticate;
}
public function getUser()
@@ -60,6 +65,10 @@ class SecurityContext
$object = new FieldVote($object, $field);
}
+ if ($this->alwaysAuthenticate || !$this->token->isAuthenticated()) {
+ $this->token = $this->authenticationManager->authenticate($this->token);
+ }
+
return $this->accessDecisionManager->decide($this->token, (array) $attributes, $object);
}
diff --git a/User/InMemoryUserProvider.php b/User/InMemoryUserProvider.php
index e83f7fa..082e9c9 100644
--- a/User/InMemoryUserProvider.php
+++ b/User/InMemoryUserProvider.php
@@ -87,4 +87,12 @@ class InMemoryUserProvider implements UserProviderInterface
return $this->loadUserByUsername((string) $account);
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supportsClass($class)
+ {
+ return $class === 'Symfony\Component\Security\User\User';
+ }
}
diff --git a/User/User.php b/User/User.php
index 4885ca0..338d43c 100644
--- a/User/User.php
+++ b/User/User.php
@@ -119,7 +119,6 @@ class User implements AdvancedAccountInterface
*/
public function eraseCredentials()
{
- $this->password = null;
}
/**
diff --git a/User/UserProviderInterface.php b/User/UserProviderInterface.php
index 4e182ee..926f575 100644
--- a/User/UserProviderInterface.php
+++ b/User/UserProviderInterface.php
@@ -36,13 +36,22 @@ interface UserProviderInterface
* Loads the user for the account interface.
*
* It is up to the implementation if it decides to reload the user data
- * from the database, or if it simply merges the passed User into the
+ * from the database, or if it simply merges the passed User into the
* identity map of an entity manager.
*
* @throws UnsupportedAccountException if the account is not supported
- * @param AccountInterface $user
+ * @param AccountInterface $account
*
* @return AccountInterface
*/
- function loadUserByAccount(AccountInterface $user);
+ function loadUserByAccount(AccountInterface $account);
+
+ /**
+ * Whether this provider supports the given user class
+ *
+ * @param string $class
+ *
+ * @return Boolean
+ */
+ function supportsClass($class);
} \ No newline at end of file