summaryrefslogtreecommitdiffstats
path: root/Authentication
diff options
context:
space:
mode:
authorJohannes Schmitt <schmittjoh@gmail.com>2010-12-08 13:51:26 +0100
committerFabien Potencier <fabien.potencier@gmail.com>2010-12-15 17:38:30 +0100
commita77e6b5f60bd1dac4d7ba19a900d72ae45d9fe26 (patch)
treea594a87afbc527dcc458d18558cf5bea3f08b1e9 /Authentication
parentb8fc4a14f4cff6bb490cf04422716a2949b6f3bc (diff)
downloadsymfony-security-a77e6b5f60bd1dac4d7ba19a900d72ae45d9fe26.zip
symfony-security-a77e6b5f60bd1dac4d7ba19a900d72ae45d9fe26.tar.gz
symfony-security-a77e6b5f60bd1dac4d7ba19a900d72ae45d9fe26.tar.bz2
fixed user refreshing after unserialization
Diffstat (limited to 'Authentication')
-rw-r--r--Authentication/Provider/DaoAuthenticationProvider.php36
-rw-r--r--Authentication/Provider/UserAuthenticationProvider.php11
-rw-r--r--Authentication/Token/Token.php74
-rw-r--r--Authentication/Token/TokenInterface.php47
-rw-r--r--Authentication/Token/UsernamePasswordToken.php5
5 files changed, 138 insertions, 35 deletions
diff --git a/Authentication/Provider/DaoAuthenticationProvider.php b/Authentication/Provider/DaoAuthenticationProvider.php
index 9a9f857..34880b2 100644
--- a/Authentication/Provider/DaoAuthenticationProvider.php
+++ b/Authentication/Provider/DaoAuthenticationProvider.php
@@ -55,12 +55,19 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider
*/
protected function checkAuthentication(AccountInterface $account, UsernamePasswordToken $token)
{
- if (!$presentedPassword = (string) $token->getCredentials()) {
- throw new BadCredentialsException('Bad credentials');
- }
+ $user = $token->getUser();
+ if ($user instanceof AccountInterface) {
+ if ($account->getPassword() !== $user->getPassword()) {
+ throw new BadCredentialsException('The credentials were changed from another session.');
+ }
+ } else {
+ if (!$presentedPassword = (string) $token->getCredentials()) {
+ throw new BadCredentialsException('Bad credentials');
+ }
- if (!$this->passwordEncoder->isPasswordValid($account->getPassword(), $presentedPassword, $account->getSalt())) {
- throw new BadCredentialsException('Bad credentials');
+ if (!$this->passwordEncoder->isPasswordValid($account->getPassword(), $presentedPassword, $account->getSalt())) {
+ throw new BadCredentialsException('Bad credentials');
+ }
}
}
@@ -69,19 +76,30 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider
*/
protected function retrieveUser($username, UsernamePasswordToken $token)
{
- $user = null;
+ $user = $token->getUser();
+ if ($user instanceof AccountInterface) {
+ return array($user, $token->getUserProviderName());
+ }
+
+ $result = null;
try {
- $user = $this->userProvider->loadUserByUsername($username);
+ $result = $this->userProvider->loadUserByUsername($username);
} catch (UsernameNotFoundException $notFound) {
throw $notFound;
} catch (\Exception $repositoryProblem) {
throw new AuthenticationServiceException($repositoryProblem->getMessage(), $token, 0, $repositoryProblem);
}
- if (!$user instanceof AccountInterface) {
+ if (!is_array($result) || 2 !== count($result)) {
+ throw new AuthenticationServiceException('User provider did not return an array, or array had invalid format.');
+ }
+ if (!$result[0] instanceof AccountInterface) {
throw new AuthenticationServiceException('The user provider must return an AccountInterface object.');
}
+ if (empty($result[1])) {
+ throw new AuthenticationServiceException('The user provider must return a non-empty user provider name.');
+ }
- return $user;
+ return $result;
}
}
diff --git a/Authentication/Provider/UserAuthenticationProvider.php b/Authentication/Provider/UserAuthenticationProvider.php
index 60c58c1..f621e42 100644
--- a/Authentication/Provider/UserAuthenticationProvider.php
+++ b/Authentication/Provider/UserAuthenticationProvider.php
@@ -54,7 +54,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
$username = null === $token->getUser() ? 'NONE_PROVIDED' : (string) $token;
try {
- $user = $this->retrieveUser($username, $token);
+ $result = $this->retrieveUser($username, $token);
} catch (UsernameNotFoundException $notFound) {
if ($this->hideUserNotFoundExceptions) {
throw new BadCredentialsException('Bad credentials', 0, $notFound);
@@ -63,15 +63,16 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
throw $notFound;
}
- if (!$user instanceof AccountInterface) {
- throw new AuthenticationServiceException('The retrieveUser() methods must return an AccountInterface object.');
+ if (!is_array($result) || 2 !== count($result)) {
+ throw new AuthenticationServiceException('retrieveUser() did not return an array, or array had invalid format.');
}
+ list($user, $userProviderName) = $result;
$this->accountChecker->checkPreAuth($user);
$this->checkAuthentication($user, $token);
$this->accountChecker->checkPostAuth($user);
- return new UsernamePasswordToken($user, $token->getCredentials(), $user->getRoles());
+ return new UsernamePasswordToken($user, $token->getCredentials(), $userProviderName, $user->getRoles());
}
/**
@@ -88,7 +89,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
* @param string $username The username to retrieve
* @param UsernamePasswordToken $token The Token
*
- * @return AccountInterface The user
+ * @return array The user
*
* @throws AuthenticationException if the credentials could not be validated
*/
diff --git a/Authentication/Token/Token.php b/Authentication/Token/Token.php
index 808f151..37b7ded 100644
--- a/Authentication/Token/Token.php
+++ b/Authentication/Token/Token.php
@@ -19,12 +19,14 @@ use Symfony\Component\Security\User\AccountInterface;
* Base class for Token instances.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
abstract class Token implements TokenInterface
{
protected $roles;
protected $authenticated;
protected $user;
+ protected $userProviderName;
protected $credentials;
protected $immutable;
@@ -35,13 +37,7 @@ abstract class Token implements TokenInterface
*/
public function __construct(array $roles = array())
{
- $this->roles = array();
- foreach ($roles as $role) {
- if (is_string($role)) {
- $role = new Role((string) $role);
- }
- $this->addRole($role);
- }
+ $this->setRoles($roles);
$this->authenticated = false;
$this->immutable = false;
}
@@ -53,6 +49,10 @@ abstract class Token implements TokenInterface
*/
public function addRole(RoleInterface $role)
{
+ if ($this->immutable) {
+ throw new \LogicException('This token is considered immutable.');
+ }
+
$this->roles[] = $role;
}
@@ -65,6 +65,22 @@ abstract class Token implements TokenInterface
}
/**
+ * {@inheritDoc}
+ */
+ public function setRoles(array $roles)
+ {
+ $this->roles = array();
+
+ foreach ($roles as $role) {
+ if (is_string($role)) {
+ $role = new Role($role);
+ }
+
+ $this->addRole($role);
+ }
+ }
+
+ /**
* {@inheritdoc}
*/
public function __toString()
@@ -91,6 +107,10 @@ abstract class Token implements TokenInterface
*/
public function setAuthenticated($authenticated)
{
+ if ($this->immutable) {
+ throw new \LogicException('This token is considered immutable.');
+ }
+
$this->authenticated = (Boolean) $authenticated;
}
@@ -111,10 +131,32 @@ abstract class Token implements TokenInterface
}
/**
+ * {@inheritDoc}
+ */
+ public function setUser($user)
+ {
+ if ($this->immutable) {
+ throw new \LogicException('This token is considered immutable.');
+ }
+
+ if (!is_string($user) && !is_object($user)) {
+ throw new \InvalidArgumentException('$user must be an object, or a primitive string.');
+ } else if (is_object($user) && !method_exists($user, '__toString')) {
+ throw new \InvalidArgumentException('If $user is an object, it must implement __toString().');
+ }
+
+ $this->user = $user;
+ }
+
+ /**
* {@inheritdoc}
*/
public function eraseCredentials()
{
+ if ($this->immutable) {
+ throw new \LogicException('This token is considered immutable.');
+ }
+
if ($this->getCredentials() instanceof AccountInterface) {
$this->getCredentials()->eraseCredentials();
}
@@ -125,6 +167,14 @@ abstract class Token implements TokenInterface
}
/**
+ * {@inheritDoc}
+ */
+ public function getUserProviderName()
+ {
+ return $this->userProviderName;
+ }
+
+ /**
* {@inheritdoc}
*/
public function isImmutable()
@@ -135,9 +185,9 @@ abstract class Token implements TokenInterface
/**
* {@inheritdoc}
*/
- public function setImmutable($value)
+ public function setImmutable()
{
- $this->immutable = (Boolean) $value;
+ $this->immutable = true;
}
/**
@@ -145,9 +195,7 @@ abstract class Token implements TokenInterface
*/
public function serialize()
{
- // FIXME: don't serialize the user object, just the username (see ContextListener)
- //return serialize(array((string) $this, $this->credentials, $this->authenticated, $this->roles, $this->immutable));
- return serialize(array($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable));
+ return serialize(array($this->user, $this->userProviderName, $this->credentials, $this->authenticated, $this->roles, $this->immutable));
}
/**
@@ -155,6 +203,6 @@ abstract class Token implements TokenInterface
*/
public function unserialize($serialized)
{
- list($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable) = unserialize($serialized);
+ list($this->user, $this->userProviderName, $this->credentials, $this->authenticated, $this->roles, $this->immutable) = unserialize($serialized);
}
}
diff --git a/Authentication/Token/TokenInterface.php b/Authentication/Token/TokenInterface.php
index 01753cf..4f37522 100644
--- a/Authentication/Token/TokenInterface.php
+++ b/Authentication/Token/TokenInterface.php
@@ -2,6 +2,8 @@
namespace Symfony\Component\Security\Authentication\Token;
+use Symfony\Component\Security\User\AccountInterface;
+
/*
* This file is part of the Symfony package.
*
@@ -33,6 +35,14 @@ interface TokenInterface extends \Serializable
function getRoles();
/**
+ * Sets the user's roles
+ *
+ * @param array $roles
+ * @return void
+ */
+ function setRoles(array $roles);
+
+ /**
* Returns the user credentials.
*
* @return mixed The user credentials
@@ -40,18 +50,27 @@ interface TokenInterface extends \Serializable
function getCredentials();
/**
- * Checks whether the token is immutable or not.
+ * Returns a user representation.
*
- * @return Boolean true if the token is immutable, false otherwise
+ * @return mixed either returns an object which implements __toString(), or
+ * a primitive string is returned.
*/
- function isImmutable();
+ function getUser();
/**
- * Returns a user instance.
+ * Sets the user.
*
- * @return object The User instance
+ * @param mixed $user can either be an object which implements __toString(), or
+ * only a primitive string
*/
- function getUser();
+ function setUser($user);
+
+ /**
+ * Returns a unique id for the user provider that was used to retrieve the user
+ *
+ * @return string
+ */
+ function getUserProviderName();
/**
* Checks if the user is authenticated or not.
@@ -68,6 +87,22 @@ interface TokenInterface extends \Serializable
function setAuthenticated($isAuthenticated);
/**
+ * Whether this token is considered immutable
+ *
+ * @return Boolean
+ */
+ function isImmutable();
+
+ /**
+ * Marks this token as immutable. This change cannot be reversed.
+ *
+ * You'll need to create a new token if you want a mutable token again.
+ *
+ * @return void
+ */
+ function setImmutable();
+
+ /**
* Removes sensitive information from the token.
*/
function eraseCredentials();
diff --git a/Authentication/Token/UsernamePasswordToken.php b/Authentication/Token/UsernamePasswordToken.php
index ae248e8..ce11cb3 100644
--- a/Authentication/Token/UsernamePasswordToken.php
+++ b/Authentication/Token/UsernamePasswordToken.php
@@ -21,12 +21,13 @@ class UsernamePasswordToken extends Token
/**
* Constructor.
*/
- public function __construct($user, $credentials, array $roles = array())
+ public function __construct($user, $credentials, $userProviderName = null, array $roles = array())
{
parent::__construct($roles);
- $this->user = $user;
+ $this->setUser($user);
$this->credentials = $credentials;
+ $this->userProviderName = $userProviderName;
parent::setAuthenticated((Boolean) count($roles));
}