summaryrefslogtreecommitdiffstats
path: root/Authentication
diff options
context:
space:
mode:
Diffstat (limited to 'Authentication')
-rw-r--r--Authentication/AuthenticationManagerInterface.php35
-rw-r--r--Authentication/AuthenticationProviderManager.php120
-rw-r--r--Authentication/EntryPoint/AuthenticationEntryPointInterface.php31
-rw-r--r--Authentication/Provider/AnonymousAuthenticationProvider.php60
-rw-r--r--Authentication/Provider/AuthenticationProviderInterface.php34
-rw-r--r--Authentication/Provider/DaoAuthenticationProvider.php88
-rw-r--r--Authentication/Provider/PreAuthenticatedAuthenticationProvider.php80
-rw-r--r--Authentication/Provider/UserAuthenticationProvider.php110
-rw-r--r--Authentication/Token/AnonymousToken.php58
-rw-r--r--Authentication/Token/PreAuthenticatedToken.php44
-rw-r--r--Authentication/Token/Token.php156
-rw-r--r--Authentication/Token/TokenInterface.php69
-rw-r--r--Authentication/Token/UsernamePasswordToken.php56
13 files changed, 941 insertions, 0 deletions
diff --git a/Authentication/AuthenticationManagerInterface.php b/Authentication/AuthenticationManagerInterface.php
new file mode 100644
index 0000000..8ab2eda
--- /dev/null
+++ b/Authentication/AuthenticationManagerInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication;
+
+use Symfony\Component\Security\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Exception\AuthenticationException;
+
+/*
+ * 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.
+ */
+
+/**
+ * AuthenticationManagerInterface is the interface for authentication managers,
+ * which process Token authentication.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface AuthenticationManagerInterface
+{
+ /**
+ * Attempts to authenticates a TokenInterface object.
+ *
+ * @param TokenInterface The TokenInterface instance to authenticate
+ *
+ * @return TokenInterface An authenticated TokenInterface instance
+ *
+ * @throws AuthenticationException if the authentication fails
+ */
+ function authenticate(TokenInterface $token);
+}
diff --git a/Authentication/AuthenticationProviderManager.php b/Authentication/AuthenticationProviderManager.php
new file mode 100644
index 0000000..1b50ccb
--- /dev/null
+++ b/Authentication/AuthenticationProviderManager.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication;
+
+use Symfony\Component\Security\Exception\AccountStatusException;
+use Symfony\Component\Security\Exception\AuthenticationException;
+use Symfony\Component\Security\Exception\ProviderNotFoundException;
+use Symfony\Component\Security\Authentication\Provider\AuthenticationProviderInterface;
+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.
+ */
+
+/**
+ * AuthenticationProviderManager uses a list of AuthenticationProviderInterface
+ * instances to authenticate a Token.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class AuthenticationProviderManager implements AuthenticationManagerInterface
+{
+ protected $providers;
+ protected $eraseCredentials;
+
+ /**
+ * Constructor.
+ *
+ * @param AuthenticationProviderInterface[] $providers An array of AuthenticationProviderInterface instances
+ * @param Boolean $eraseCredentials Whether to erase credentials after authentication or not
+ */
+ public function __construct(array $providers = array(), $eraseCredentials = true)
+ {
+ $this->setProviders($providers);
+ $this->eraseCredentials = $eraseCredentials;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(TokenInterface $token)
+ {
+ if (!count($this->providers)) {
+ throw new \LogicException('You must add at least one provider.');
+ }
+
+ $lastException = null;
+ $result = null;
+
+ foreach ($this->providers as $provider) {
+ if (!$provider->supports($token)) {
+ continue;
+ }
+
+ try {
+ $result = $provider->authenticate($token);
+ } catch (AccountStatusException $e) {
+ $e->setToken($token);
+
+ throw $e;
+ } catch (AuthenticationException $e) {
+ $lastException = $e;
+ }
+ }
+
+ if (null !== $result) {
+ if ($this->eraseCredentials) {
+ $result->eraseCredentials();
+ }
+
+ return $result;
+ }
+
+ if (null === $lastException) {
+ $lastException = new ProviderNotFoundException(sprintf('No Authentication Provider found for token of class "%s".', get_class($token)));
+ }
+
+ $lastException->setToken($token);
+
+ throw $lastException;
+ }
+
+ /**
+ * Returns the list of current providers.
+ *
+ * @return AuthenticationProviderInterface[] An array of AuthenticationProviderInterface instances
+ */
+ public function getProviders()
+ {
+ return $this->providers;
+ }
+
+ /**
+ * Sets the providers instances.
+ *
+ * @param AuthenticationProviderInterface[] $providers An array of AuthenticationProviderInterface instances
+ */
+ public function setProviders(array $providers)
+ {
+ $this->providers = array();
+ foreach ($providers as $provider) {
+ $this->addProvider($provider);
+ }
+ }
+
+ /**
+ * Adds a provider.
+ *
+ * @param AuthenticationProviderInterface $provider A AuthenticationProviderInterface instance
+ */
+ public function addProvider(AuthenticationProviderInterface $provider)
+ {
+ $this->providers[] = $provider;
+ }
+}
diff --git a/Authentication/EntryPoint/AuthenticationEntryPointInterface.php b/Authentication/EntryPoint/AuthenticationEntryPointInterface.php
new file mode 100644
index 0000000..dc825c1
--- /dev/null
+++ b/Authentication/EntryPoint/AuthenticationEntryPointInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\EntryPoint;
+
+use Symfony\Component\Security\Exception\AuthenticationException;
+use Symfony\Component\HttpFoundation\Request;
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+/**
+ * AuthenticationEntryPointInterface is the interface used to start the authentication scheme.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface AuthenticationEntryPointInterface
+{
+ /**
+ * Starts the authentication scheme.
+ *
+ * @param object $request The request that resulted in an AuthenticationException
+ * @param AuthenticationException $authException The exception that started the authentication process
+ */
+ function start(Request $request, AuthenticationException $authException = null);
+}
diff --git a/Authentication/Provider/AnonymousAuthenticationProvider.php b/Authentication/Provider/AnonymousAuthenticationProvider.php
new file mode 100644
index 0000000..67671b5
--- /dev/null
+++ b/Authentication/Provider/AnonymousAuthenticationProvider.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\Provider;
+
+use Symfony\Component\Security\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Exception\BadCredentialsException;
+use Symfony\Component\Security\Authentication\Token\AnonymousToken;
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+/**
+ * AnonymousAuthenticationProvider validates AnonymousToken instances.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class AnonymousAuthenticationProvider implements AuthenticationProviderInterface
+{
+ protected $key;
+
+ /**
+ * Constructor.
+ *
+ * @param string $key The key shared with the authentication token
+ */
+ public function __construct($key)
+ {
+ $this->key;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(TokenInterface $token)
+ {
+ if (!$this->supports($token)) {
+ return null;
+ }
+
+ if ($this->key != $token->getKey()) {
+ throw new BadCredentialsException('The Token does not contain the expected key.');
+ }
+
+ return $token;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($token)
+ {
+ return $token instanceof AnonymousToken;
+ }
+}
diff --git a/Authentication/Provider/AuthenticationProviderInterface.php b/Authentication/Provider/AuthenticationProviderInterface.php
new file mode 100644
index 0000000..61a428b
--- /dev/null
+++ b/Authentication/Provider/AuthenticationProviderInterface.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\Provider;
+
+use Symfony\Component\Security\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Authentication\AuthenticationManagerInterface;
+
+/*
+ * 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.
+ */
+
+/**
+ * AuthenticationProviderInterface is the interface for for all authentication providers.
+ *
+ * Concrete implementations processes specific Token instances.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface AuthenticationProviderInterface extends AuthenticationManagerInterface
+{
+ /**
+ * Checks whether this provider supports the given token.
+ *
+ * @param TokenInterface $token A TokenInterface instance
+ *
+ * @return Boolean true if the implementation supports the Token, false otherwise
+ */
+ function supports(TokenInterface $token);
+}
diff --git a/Authentication/Provider/DaoAuthenticationProvider.php b/Authentication/Provider/DaoAuthenticationProvider.php
new file mode 100644
index 0000000..f814988
--- /dev/null
+++ b/Authentication/Provider/DaoAuthenticationProvider.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\Provider;
+
+use Symfony\Component\Security\User\UserProviderInterface;
+use Symfony\Component\Security\User\AccountCheckerInterface;
+use Symfony\Component\Security\User\AccountInterface;
+use Symfony\Component\Security\Encoder\PasswordEncoderInterface;
+use Symfony\Component\Security\Encoder\PlaintextPasswordEncoder;
+use Symfony\Component\Security\Exception\UsernameNotFoundException;
+use Symfony\Component\Security\Exception\AuthenticationServiceException;
+use Symfony\Component\Security\Exception\BadCredentialsException;
+use Symfony\Component\Security\Authentication\Token\UsernamePasswordToken;
+
+/*
+ * 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.
+ */
+
+/**
+ * DaoAuthenticationProvider uses a UserProviderInterface to retrieve the user for a UsernamePasswordToken.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class DaoAuthenticationProvider extends UserAuthenticationProvider
+{
+ protected $passwordEncoder;
+ protected $userProvider;
+
+ /**
+ * Constructor.
+ *
+ * @param UserProviderInterface $userProvider A UserProviderInterface instance
+ * @param PasswordEncoderInterface $passwordEncoder A PasswordEncoderInterface instance
+ * @param AccountCheckerInterface $accountChecker An AccountCheckerInterface instance
+ */
+ public function __construct(UserProviderInterface $userProvider, AccountCheckerInterface $accountChecker, PasswordEncoderInterface $passwordEncoder = null)
+ {
+ parent::__construct($accountChecker);
+
+ if (null === $passwordEncoder) {
+ $passwordEncoder = new PlaintextPasswordEncoder();
+ }
+ $this->passwordEncoder = $passwordEncoder;
+ $this->userProvider = $userProvider;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function checkAuthentication(AccountInterface $account, UsernamePasswordToken $token)
+ {
+ if (null === $token->getCredentials()) {
+ throw new BadCredentialsException('Bad credentials');
+ }
+
+ $presentedPassword = (string) $token->getCredentials();
+
+ if (!$this->passwordEncoder->isPasswordValid($account->getPassword(), $presentedPassword, $account->getSalt())) {
+ throw new BadCredentialsException('Bad credentials');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function retrieveUser($username, UsernamePasswordToken $token)
+ {
+ $user = null;
+ try {
+ $user = $this->userProvider->loadUserByUsername($username);
+ } catch (UsernameNotFoundException $notFound) {
+ throw $notFound;
+ } catch (\Exception $repositoryProblem) {
+ throw new AuthenticationServiceException($repositoryProblem->getMessage(), $token, 0, $repositoryProblem);
+ }
+
+ if (null === $user) {
+ throw new AuthenticationServiceException('UserProvider returned null.');
+ }
+
+ return $user;
+ }
+}
diff --git a/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php b/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php
new file mode 100644
index 0000000..8617fdb
--- /dev/null
+++ b/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\Provider;
+
+use Symfony\Component\Security\User\UserProviderInterface;
+use Symfony\Component\Security\User\AccountCheckerInterface;
+use Symfony\Component\Security\Exception\BadCredentialsException;
+use Symfony\Component\Security\Authentication\Token\PreAuthenticatedToken;
+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.
+ */
+
+/**
+ * Processes a pre-authenticated authentication request. The request will
+ * typically originate from a {@link org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter}
+ * subclass.
+ *
+ * This authentication provider will not perform any checks on authentication
+ * requests, as they should already be pre-authenticated. However, the
+ * AuthenticationUserDetailsService implementation may still throw a UsernameNotFoundException, for example.
+ *
+ * @author Ruud Senden
+ * @since 2.0
+ */
+class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderInterface
+{
+ protected $userProvider;
+ protected $accountChecker;
+
+ /**
+ * Constructor.
+ *
+ * @param UserProviderInterface $userProvider A UserProviderInterface instance
+ * @param AccountCheckerInterface $accountChecker An AccountCheckerInterface instance
+ */
+ public function __construct(UserProviderInterface $userProvider, AccountCheckerInterface $accountChecker)
+ {
+ $this->userProvider = $userProvider;
+ $this->accountChecker = $accountChecker;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(TokenInterface $token)
+ {
+ if (!$this->supports($token)) {
+ return null;
+ }
+
+ if (null === $token->getUser()) {
+ throw new BadCredentialsException('No pre-authenticated principal found in request.');
+ }
+/*
+ if (null === $token->getCredentials()) {
+ throw new BadCredentialsException('No pre-authenticated credentials found in request.');
+ }
+*/
+ $user = $this->userProvider->loadUserByUsername($token->getUser());
+
+ $this->accountChecker->checkPostAuth($user);
+
+ return new PreAuthenticatedToken($user, $token->getCredentials(), $user->getRoles());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports(TokenInterface $token)
+ {
+ return $token instanceof PreAuthenticatedToken;
+ }
+}
diff --git a/Authentication/Provider/UserAuthenticationProvider.php b/Authentication/Provider/UserAuthenticationProvider.php
new file mode 100644
index 0000000..ddd98c3
--- /dev/null
+++ b/Authentication/Provider/UserAuthenticationProvider.php
@@ -0,0 +1,110 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\Provider;
+
+use Symfony\Component\Security\User\AccountInterface;
+use Symfony\Component\Security\User\AccountCheckerInterface;
+use Symfony\Component\Security\Exception\UsernameNotFoundException;
+use Symfony\Component\Security\Exception\AuthenticationException;
+use Symfony\Component\Security\Exception\BadCredentialsException;
+use Symfony\Component\Security\Authentication\Token\UsernamePasswordToken;
+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.
+ */
+
+/**
+ * UserProviderInterface retrieves users for UsernamePasswordToken tokens.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+abstract class UserAuthenticationProvider implements AuthenticationProviderInterface
+{
+ protected $hideUserNotFoundExceptions;
+ protected $accountChecker;
+
+ /**
+ * Constructor.
+ *
+ * @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)
+ {
+ $this->accountChecker = $accountChecker;
+ $this->hideUserNotFoundExceptions = $hideUserNotFoundExceptions;
+ }
+
+ /**
+ * Does additional checks on the user and token (like validating the credentials).
+ *
+ * @param AccountInterface $account The retrieved AccountInterface instance
+ * @param UsernamePasswordToken $token The UsernamePasswordToken token to be authenticated
+ *
+ * @throws AuthenticationException if the credentials could not be validated
+ */
+ abstract protected function checkAuthentication(AccountInterface $account, UsernamePasswordToken $token);
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(TokenInterface $token)
+ {
+ if (!$this->supports($token)) {
+ return null;
+ }
+
+ $username = null === $token->getUser() ? 'NONE_PROVIDED' : (string) $token;
+
+ try {
+ $user = $this->retrieveUser($username, $token);
+ } catch (UsernameNotFoundException $notFound) {
+ if ($this->hideUserNotFoundExceptions) {
+ throw new BadCredentialsException('Bad credentials', 0, $notFound);
+ }
+
+ throw $notFound;
+ }
+
+ if (null === $user) {
+ throw new \LogicException('The retrieveUser() methods returned null which should not be possible.');
+ }
+
+ try {
+ $this->accountChecker->checkPreAuth($user);
+ $this->checkAuthentication($user, $token);
+ } catch (AuthenticationException $e) {
+ throw $e;
+ }
+
+ $this->accountChecker->checkPostAuth($user);
+
+ return new UsernamePasswordToken($user, $token->getCredentials(), $user->getRoles());
+ }
+
+ /**
+ * Retrieves the user from an implementation-specific location.
+ *
+ * @param string $username The username to retrieve
+ * @param UsernamePasswordToken $token The Token
+ *
+ * @return mixed The user
+ *
+ * @throws AuthenticationException if the credentials could not be validated
+ */
+ abstract protected function retrieveUser($username, UsernamePasswordToken $token);
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports(TokenInterface $token)
+ {
+ return $token instanceof UsernamePasswordToken;
+ }
+}
diff --git a/Authentication/Token/AnonymousToken.php b/Authentication/Token/AnonymousToken.php
new file mode 100644
index 0000000..c8fb1aa
--- /dev/null
+++ b/Authentication/Token/AnonymousToken.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\Token;
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+/**
+ * AnonymousToken represents an anonymous token.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class AnonymousToken extends Token
+{
+ protected $user;
+ protected $key;
+
+ /**
+ * Constructor.
+ *
+ * @param string $key The key shared with the authentication provider
+ * @param string $user The user
+ * @param Role[] $roles An array of roles
+ */
+ public function __construct($key, $user, array $roles = array())
+ {
+ parent::__construct($roles);
+
+ $this->key = $key;
+ $this->user = $user;
+
+ parent::setAuthenticated(true);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCredentials()
+ {
+ return '';
+ }
+
+ /**
+ * Returns the key.
+ *
+ * @return string The Key
+ */
+ public function getKey()
+ {
+ return $this->key;
+ }
+}
diff --git a/Authentication/Token/PreAuthenticatedToken.php b/Authentication/Token/PreAuthenticatedToken.php
new file mode 100644
index 0000000..7466757
--- /dev/null
+++ b/Authentication/Token/PreAuthenticatedToken.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\Token;
+
+/*
+ * 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.
+ */
+
+/**
+ * PreAuthenticatedToken implements a pre-authenticated token.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class PreAuthenticatedToken extends Token
+{
+ /**
+ * Constructor.
+ */
+ public function __construct($user, $credentials, array $roles = null)
+ {
+ if (null !== $roles) {
+ parent::__construct($roles);
+ $this->setAuthenticated(true);
+ }
+
+ $this->user = $user;
+ $this->credentials = $credentials;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function eraseCredentials()
+ {
+ parent::eraseCredentials();
+
+ $this->credentials = null;
+ }
+}
diff --git a/Authentication/Token/Token.php b/Authentication/Token/Token.php
new file mode 100644
index 0000000..8279363
--- /dev/null
+++ b/Authentication/Token/Token.php
@@ -0,0 +1,156 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\Token;
+
+use Symfony\Component\Security\Role\RoleInterface;
+use Symfony\Component\Security\Role\Role;
+use Symfony\Component\Security\User\AccountInterface;
+
+/*
+ * 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.
+ */
+
+/**
+ * Base class for Token instances.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+abstract class Token implements TokenInterface
+{
+ protected $roles;
+ protected $authenticated;
+ protected $user;
+ protected $credentials;
+ protected $immutable;
+
+ /**
+ * Constructor.
+ *
+ * @param Role[] An array of roles
+ */
+ 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);
+ }
+ }
+
+ /**
+ * Adds a Role to the token.
+ *
+ * @param RoleInterface A RoleInterface instance
+ */
+ public function addRole(RoleInterface $role)
+ {
+ $this->roles[] = $role;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRoles()
+ {
+ return $this->roles;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __toString()
+ {
+ if (!is_object($this->user)) {
+ return (string) $this->user;
+ } else {
+ return $this->user->getUsername();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isAuthenticated()
+ {
+ return $this->authenticated;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setAuthenticated($authenticated)
+ {
+ $this->authenticated = (Boolean) $authenticated;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCredentials()
+ {
+ return $this->credentials;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getUser()
+ {
+ return $this->user;
+ }
+
+ /**
+ * Removes sensitive information from the token.
+ */
+ public function eraseCredentials()
+ {
+ if ($this->getCredentials() instanceof AccountInterface) {
+ $this->getCredentials()->eraseCredentials();
+ }
+
+ if ($this->getUser() instanceof AccountInterface) {
+ $this->getUser()->eraseCredentials();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isImmutable()
+ {
+ return $this->immutable;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setImmutable($value)
+ {
+ $this->immutable = (Boolean) $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ 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));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function unserialize($serialized)
+ {
+ list($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable) = unserialize($serialized);
+ }
+}
diff --git a/Authentication/Token/TokenInterface.php b/Authentication/Token/TokenInterface.php
new file mode 100644
index 0000000..1300716
--- /dev/null
+++ b/Authentication/Token/TokenInterface.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\Token;
+
+/*
+ * 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.
+ */
+
+/**
+ * TokenInterface is the interface for the user authentication information.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface TokenInterface extends \Serializable
+{
+ /**
+ * Returns a string representation of the token.
+ *
+ * @return string A string representation
+ */
+ public function __toString();
+
+ /**
+ * Returns the user roles.
+ *
+ * @return Role[] An array of Role instances.
+ */
+ function getRoles();
+
+ /**
+ * Returns the user credentials.
+ *
+ * @return mixed The user credentials
+ */
+ function getCredentials();
+
+ /**
+ * Checks whether the token is immutable or not.
+ *
+ * @return Boolean true if the token is immutable, false otherwise
+ */
+ function isImmutable();
+
+ /**
+ * Returns a user instance.
+ *
+ * @return object The User instance
+ */
+ function getUser();
+
+ /**
+ * Checks if the user is authenticated or not.
+ *
+ * @return Boolean true if the token has been authenticated, false otherwise
+ */
+ function isAuthenticated();
+
+ /**
+ * Sets the authenticated flag.
+ *
+ * @param Boolean The authenticated flag
+ */
+ function setAuthenticated($isAuthenticated);
+}
diff --git a/Authentication/Token/UsernamePasswordToken.php b/Authentication/Token/UsernamePasswordToken.php
new file mode 100644
index 0000000..5356f8d
--- /dev/null
+++ b/Authentication/Token/UsernamePasswordToken.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Symfony\Component\Security\Authentication\Token;
+
+/*
+ * 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.
+ */
+
+/**
+ * UsernamePasswordToken implements a username and password token.
+ *
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class UsernamePasswordToken extends Token
+{
+ /**
+ * Constructor.
+ */
+ public function __construct($user, $credentials, array $roles = array())
+ {
+ parent::__construct($roles);
+
+ $this->user = $user;
+ $this->credentials = $credentials;
+
+ parent::setAuthenticated((Boolean) count($roles));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setAuthenticated($isAuthenticated)
+ {
+ if ($isAuthenticated)
+ {
+ throw new \LogicException('Cannot set this token to trusted after instantiation.');
+ }
+
+ parent::setAuthenticated(false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function eraseCredentials()
+ {
+ parent::eraseCredentials();
+
+ $this->credentials = null;
+ }
+}