diff options
4 files changed, 227 insertions, 0 deletions
diff --git a/Core/Authentication/Provider/SimpleAuthenticationProvider.php b/Core/Authentication/Provider/SimpleAuthenticationProvider.php new file mode 100644 index 0000000..72b82cb --- /dev/null +++ b/Core/Authentication/Provider/SimpleAuthenticationProvider.php @@ -0,0 +1,56 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\Authentication\Provider; + +use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; +use Symfony\Component\Security\Core\User\UserProviderInterface; +use Symfony\Component\Security\Core\User\UserCheckerInterface; +use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; +use Symfony\Component\Security\Core\Exception\AuthenticationServiceException; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface; +use Symfony\Component\Security\Core\Exception\AuthenticationException; + +/** + * @author Jordi Boggiano <j.boggiano@seld.be> + */ +class SimpleAuthenticationProvider implements AuthenticationProviderInterface +{ + private $simpleAuthenticator; + private $userProvider; + private $providerKey; + + public function __construct(SimpleAuthenticatorInterface $simpleAuthenticator, UserProviderInterface $userProvider, $providerKey) + { + $this->simpleAuthenticator = $simpleAuthenticator; + $this->userProvider = $userProvider; + $this->providerKey = $providerKey; + } + + public function authenticate(TokenInterface $token) + { + $authToken = $this->simpleAuthenticator->authenticate($token, $this->userProvider, $this->providerKey); + + if ($authToken instanceof TokenInterface) { + return $authToken; + } + + throw new AuthenticationException('Simple authenticator failed to return an authenticated token.'); + } + + public function supports(TokenInterface $token) + { + return $this->simpleAuthenticator->supports($token, $this->providerKey); + } +} diff --git a/Core/Authentication/SimpleAuthenticatorInterface.php b/Core/Authentication/SimpleAuthenticatorInterface.php new file mode 100644 index 0000000..81f761f --- /dev/null +++ b/Core/Authentication/SimpleAuthenticatorInterface.php @@ -0,0 +1,30 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\Authentication; + +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\User\UserProviderInterface; + +/** + * @author Jordi Boggiano <j.boggiano@seld.be> + */ +interface SimpleAuthenticatorInterface +{ + public function authenticate(TokenInterface $token, UserProviderInterface $userProvider, $providerKey); + + public function supports(TokenInterface $token, $providerKey); + + public function handleAuthenticationFailure(GetResponseEvent $event, AuthenticationException $exception); +} diff --git a/Core/Authentication/SimpleFormAuthenticatorInterface.php b/Core/Authentication/SimpleFormAuthenticatorInterface.php new file mode 100644 index 0000000..79fdb1c --- /dev/null +++ b/Core/Authentication/SimpleFormAuthenticatorInterface.php @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\Authentication; + +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpFoundation\Request; + +/** + * @author Jordi Boggiano <j.boggiano@seld.be> + */ +interface SimpleFormAuthenticatorInterface extends SimpleAuthenticatorInterface +{ + public function createToken(Request $request, $username, $password, $providerKey); +} diff --git a/Http/Firewall/SimpleFormAuthenticationListener.php b/Http/Firewall/SimpleFormAuthenticationListener.php new file mode 100644 index 0000000..f096c2f --- /dev/null +++ b/Http/Firewall/SimpleFormAuthenticationListener.php @@ -0,0 +1,116 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Http\Firewall; + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; +use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; +use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; +use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; +use Symfony\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\Security\Core\Exception\SessionUnavailableException; +use Symfony\Component\Security\Core\SecurityContextInterface; +use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; +use Symfony\Component\Security\Http\HttpUtils; +use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; +use Symfony\Component\Security\Http\SecurityEvents; +use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; + +/** + * @author Jordi Boggiano <j.boggiano@seld.be> + */ +class SimpleFormAuthenticationListener extends AbstractAuthenticationListener +{ + private $simpleAuthenticator; + private $csrfProvider; + + /** + * Constructor. + * + * @param SecurityContextInterface $securityContext A SecurityContext instance + * @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance + * @param SessionAuthenticationStrategyInterface $sessionStrategy + * @param HttpUtils $httpUtils An HttpUtilsInterface instance + * @param string $providerKey + * @param AuthenticationSuccessHandlerInterface $successHandler + * @param AuthenticationFailureHandlerInterface $failureHandler + * @param array $options An array of options for the processing of a + * successful, or failed authentication attempt + * @param LoggerInterface $logger A LoggerInterface instance + * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance + * @param SimpleFormAuthenticatorInterface $simpleAuthenticator A SimpleFormAuthenticatorInterface instance + * @param CsrfProviderInterface $csrfProvider A CsrfProviderInterface instance + */ + public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfProviderInterface $csrfProvider = null, SimpleFormAuthenticatorInterface $simpleAuthenticator = null) + { + if (!$simpleAuthenticator) { + throw new \InvalidArgumentException('Missing simple authenticator'); + } + + $this->simpleAuthenticator = $simpleAuthenticator; + $this->csrfProvider = $csrfProvider; + + $options = array_merge(array( + 'username_parameter' => '_username', + 'password_parameter' => '_password', + 'csrf_parameter' => '_csrf_token', + 'intention' => 'authenticate', + 'post_only' => true, + ), $options); + parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, $options, $logger, $dispatcher); + } + + /** + * {@inheritdoc} + */ + protected function requiresAuthentication(Request $request) + { + if ($this->options['post_only'] && !$request->isMethod('POST')) { + return false; + } + + return parent::requiresAuthentication($request); + } + + /** + * {@inheritdoc} + */ + protected function attemptAuthentication(Request $request) + { + if (null !== $this->csrfProvider) { + $csrfToken = $request->get($this->options['csrf_parameter'], null, true); + + if (false === $this->csrfProvider->isCsrfTokenValid($this->options['intention'], $csrfToken)) { + throw new InvalidCsrfTokenException('Invalid CSRF token.'); + } + } + + if ($this->options['post_only']) { + $username = trim($request->request->get($this->options['username_parameter'], null, true)); + $password = $request->request->get($this->options['password_parameter'], null, true); + } else { + $username = trim($request->get($this->options['username_parameter'], null, true)); + $password = $request->get($this->options['password_parameter'], null, true); + } + + $request->getSession()->set(SecurityContextInterface::LAST_USERNAME, $username); + + $token = $this->simpleAuthenticator->createToken($request, $username, $password, $this->providerKey); + + return $this->authenticationManager->authenticate($token); + } +} |