diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SimpleFormFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SimpleFormFactory.php index 1acbde25a1..fc1344db25 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SimpleFormFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SimpleFormFactory.php @@ -28,6 +28,8 @@ class SimpleFormFactory extends FormLoginFactory $this->addOption('authenticator', null); } +// TODO create proxies for success_handler/failure_handler that call the impl ones then the default ones by default if no response is returned + public function getKey() { return 'simple-form'; diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SimpleTokenFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SimpleTokenFactory.php new file mode 100644 index 0000000000..beca6a81b9 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SimpleTokenFactory.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @author Jordi Boggiano + */ +class SimpleTokenFactory implements SecurityFactoryInterface +{ + public function getPosition() + { + return 'http'; + } + + public function getKey() + { + return 'simple-token'; + } + +// TODO add support for success_handler/failure_handler that call the impl ones + + public function addConfiguration(NodeDefinition $node) + { + $node + ->children() + ->scalarNode('provider')->end() + ->scalarNode('authenticator')->cannotBeEmpty()->end() + ->end() + ; + } + + public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint) + { + $provider = 'security.authentication.provider.simple_form.'.$id; + $container + ->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.simple')) + ->replaceArgument(0, new Reference($config['authenticator'])) + ->replaceArgument(1, new Reference($userProvider)) + ->replaceArgument(2, $id) + ; + + // listener + $listenerId = 'security.authentication.listener.simple_token.'.$id; + $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.simple_token')); + $listener->replaceArgument(2, $id); + $listener->replaceArgument(3, new Reference($config['authenticator'])); + + return array($provider, $listenerId); + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml index 88c70b383d..d9dea17af6 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml @@ -14,6 +14,8 @@ Symfony\Component\Security\Http\Firewall\SimpleFormAuthenticationListener + Symfony\Component\Security\Http\Firewall\SimpleTokenAuthenticationListener + Symfony\Component\Security\Http\Firewall\BasicAuthenticationListener Symfony\Component\Security\Http\EntryPoint\BasicAuthenticationEntryPoint @@ -142,6 +144,15 @@ abstract="true"> + + + + + + + + + diff --git a/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php b/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php index 2796c232ad..cbdc69f521 100644 --- a/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php +++ b/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php @@ -19,6 +19,7 @@ use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\HttpBasic use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\HttpDigestFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\RememberMeFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\X509Factory; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SimpleTokenFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SimpleFormFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\InMemoryFactory; @@ -39,6 +40,7 @@ class SecurityBundle extends Bundle $extension->addSecurityListenerFactory(new HttpDigestFactory()); $extension->addSecurityListenerFactory(new RememberMeFactory()); $extension->addSecurityListenerFactory(new X509Factory()); + $extension->addSecurityListenerFactory(new SimpleTokenFactory()); $extension->addSecurityListenerFactory(new SimpleFormFactory()); $extension->addUserProviderFactory(new InMemoryFactory()); diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php index 72b82cba35..8f8ccebb43 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php +++ b/src/Symfony/Component/Security/Core/Authentication/Provider/SimpleAuthenticationProvider.php @@ -40,7 +40,7 @@ class SimpleAuthenticationProvider implements AuthenticationProviderInterface public function authenticate(TokenInterface $token) { - $authToken = $this->simpleAuthenticator->authenticate($token, $this->userProvider, $this->providerKey); + $authToken = $this->simpleAuthenticator->authenticateToken($token, $this->userProvider, $this->providerKey); if ($authToken instanceof TokenInterface) { return $authToken; @@ -51,6 +51,6 @@ class SimpleAuthenticationProvider implements AuthenticationProviderInterface public function supports(TokenInterface $token) { - return $this->simpleAuthenticator->supports($token, $this->providerKey); + return $this->simpleAuthenticator->supportsToken($token, $this->providerKey); } } diff --git a/src/Symfony/Component/Security/Core/Authentication/SimpleAuthenticatorInterface.php b/src/Symfony/Component/Security/Core/Authentication/SimpleAuthenticatorInterface.php index 81f761fd9f..fbbaa37bbb 100644 --- a/src/Symfony/Component/Security/Core/Authentication/SimpleAuthenticatorInterface.php +++ b/src/Symfony/Component/Security/Core/Authentication/SimpleAuthenticatorInterface.php @@ -13,18 +13,19 @@ 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; +use Symfony\Component\HttpFoundation\Request; /** * @author Jordi Boggiano */ interface SimpleAuthenticatorInterface { - public function authenticate(TokenInterface $token, UserProviderInterface $userProvider, $providerKey); + public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey); - public function supports(TokenInterface $token, $providerKey); + public function supportsToken(TokenInterface $token, $providerKey); - public function handleAuthenticationFailure(GetResponseEvent $event, AuthenticationException $exception); + public function onAuthenticationFailure(Request $request, AuthenticationException $exception); + + public function onAuthenticationSuccess(Request $request, TokenInterface $token); } diff --git a/src/Symfony/Component/Security/Core/Authentication/SimpleFormAuthenticatorInterface.php b/src/Symfony/Component/Security/Core/Authentication/SimpleFormAuthenticatorInterface.php index 79fdb1cb3c..95ee881c18 100644 --- a/src/Symfony/Component/Security/Core/Authentication/SimpleFormAuthenticatorInterface.php +++ b/src/Symfony/Component/Security/Core/Authentication/SimpleFormAuthenticatorInterface.php @@ -11,9 +11,6 @@ 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; /** diff --git a/src/Symfony/Component/Security/Core/Authentication/SimpleTokenAuthenticatorInterface.php b/src/Symfony/Component/Security/Core/Authentication/SimpleTokenAuthenticatorInterface.php new file mode 100644 index 0000000000..a6117544d4 --- /dev/null +++ b/src/Symfony/Component/Security/Core/Authentication/SimpleTokenAuthenticatorInterface.php @@ -0,0 +1,22 @@ + + * + * 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\HttpFoundation\Request; + +/** + * @author Jordi Boggiano + */ +interface SimpleTokenAuthenticatorInterface extends SimpleAuthenticatorInterface +{ + public function createToken(Request $request, $providerKey); +} diff --git a/src/Symfony/Component/Security/Http/Firewall/SimpleTokenAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/SimpleTokenAuthenticationListener.php new file mode 100644 index 0000000000..cda535b009 --- /dev/null +++ b/src/Symfony/Component/Security/Http/Firewall/SimpleTokenAuthenticationListener.php @@ -0,0 +1,90 @@ + + * + * 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\Security\Core\SecurityContextInterface; +use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; +use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\Security\Core\Authentication\SimpleTokenAuthenticatorInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Exception\AuthenticationException; + +/** + * SimpleTokenListener implements simple proxying to an authenticator. + * + * @author Jordi Boggiano + */ +class SimpleTokenAuthenticationListener implements ListenerInterface +{ + private $securityContext; + private $authenticationManager; + private $providerKey; + private $simpleAuthenticator; + private $logger; + + /** + * Constructor. + * + * @param SecurityContextInterface $securityContext A SecurityContext instance + * @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance + * @param string $providerKey + * @param SimpleTokenAuthenticatorInterface $simpleAuthenticator A SimpleTokenAuthenticatorInterface instance + * @param LoggerInterface $logger A LoggerInterface instance + */ + public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, $providerKey, SimpleTokenAuthenticatorInterface $simpleAuthenticator, LoggerInterface $logger = null) + { + if (empty($providerKey)) { + throw new \InvalidArgumentException('$providerKey must not be empty.'); + } + + $this->securityContext = $securityContext; + $this->authenticationManager = $authenticationManager; + $this->providerKey = $providerKey; + $this->simpleAuthenticator = $simpleAuthenticator; + $this->logger = $logger; + } + + /** + * Handles basic authentication. + * + * @param GetResponseEvent $event A GetResponseEvent instance + */ + public function handle(GetResponseEvent $event) + { + $request = $event->getRequest(); + + if (null !== $this->logger) { + $this->logger->info(sprintf('Attempting simple token authorization %s', $this->providerKey)); + } + + + try { + $token = $this->simpleAuthenticator->createToken($request, $this->providerKey); + $token = $this->authenticationManager->authenticate($token); + $this->securityContext->setToken($token); + + } catch (AuthenticationException $failed) { + $this->securityContext->setToken(null); + + if (null !== $this->logger) { + $this->logger->info(sprintf('Authentication request failed: %s', $failed->getMessage())); + } + + // TODO call failure handler + return; + } + + // TODO call success handler + } +}