diff options
author | Fabien Potencier <fabien.potencier@gmail.com> | 2010-10-19 13:06:43 +0200 |
---|---|---|
committer | Fabien Potencier <fabien.potencier@gmail.com> | 2010-10-19 13:33:17 +0200 |
commit | 3fec93d3ff1f6a31f078e5558a15a75539bf5185 (patch) | |
tree | 1a6229643289d9d0ca55871bab9497035a6e49f1 /Authentication/Provider | |
download | symfony-security-3fec93d3ff1f6a31f078e5558a15a75539bf5185.zip symfony-security-3fec93d3ff1f6a31f078e5558a15a75539bf5185.tar.gz symfony-security-3fec93d3ff1f6a31f078e5558a15a75539bf5185.tar.bz2 |
added the Security Component and its integration into the MVC framework
Happy birthday symfony!
Diffstat (limited to 'Authentication/Provider')
5 files changed, 372 insertions, 0 deletions
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; + } +} |