diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php
index 3fdb104cc8a87..879a0cbf2a800 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php
@@ -26,16 +26,19 @@
*/
abstract class AbstractFactory implements SecurityFactoryInterface
{
- protected $options = array(
+ protected $listenerOptions = array(
'check_path' => '/login_check',
'login_path' => '/login',
'use_forward' => false,
+ 'failure_path' => null,
+ 'failure_forward' => false,
+ );
+
+ protected $targetUrlGeneratorOptions = array(
'always_use_default_target_path' => false,
'default_target_path' => '/',
'target_path_parameter' => '_target_path',
- 'use_referer' => false,
- 'failure_path' => null,
- 'failure_forward' => false,
+ 'use_referer' => false
);
public function create(ContainerBuilder $container, $id, $config, $userProviderId, $defaultEntryPointId)
@@ -43,8 +46,11 @@ public function create(ContainerBuilder $container, $id, $config, $userProviderI
// authentication provider
$authProviderId = $this->createAuthProvider($container, $id, $config, $userProviderId);
+ // target url generator
+ $targetUrlGeneratorId = $this->createTargetUrlGenerator($container, $id, $config);
+
// authentication listener
- $listenerId = $this->createListener($container, $id, $config, $userProviderId);
+ $listenerId = $this->createListener($container, $id, $config, $userProviderId, $targetUrlGeneratorId);
// add remember-me aware tag if requested
if ($this->isRememberMeAware($config)) {
@@ -69,7 +75,7 @@ public function addConfiguration(NodeBuilder $node)
->scalarNode('failure_handler')->end()
;
- foreach ($this->options as $name => $default) {
+ foreach (array_merge($this->listenerOptions, $this->targetUrlGeneratorOptions) as $name => $default) {
if (is_bool($default)) {
$node->booleanNode($name)->defaultValue($default);
} else {
@@ -80,7 +86,7 @@ public function addConfiguration(NodeBuilder $node)
public final function addOption($name, $default = null)
{
- $this->options[$name] = $default;
+ $this->listenerOptions[$name] = $default;
}
/**
@@ -142,21 +148,22 @@ protected function isRememberMeAware($config)
return $config['remember_me'];
}
- protected function createListener($container, $id, $config, $userProvider)
+ protected function createListener($container, $id, $config, $userProvider, $targetUrlGenerator)
{
$listenerId = $this->getListenerId();
$listener = new DefinitionDecorator($listenerId);
- $listener->setArgument(3, $id);
- $listener->setArgument(4, array_intersect_key($config, $this->options));
+ $listener->setArgument(3, new Reference($targetUrlGenerator));
+ $listener->setArgument(4, $id);
+ $listener->setArgument(5, array_intersect_key($config, $this->listenerOptions));
// success handler
if (isset($config['success_handler'])) {
- $listener->setArgument(5, new Reference($config['success_handler']));
+ $listener->setArgument(6, new Reference($config['success_handler']));
}
// failure handler
if (isset($config['failure_handler'])) {
- $listener->setArgument(6, new Reference($config['failure_handler']));
+ $listener->setArgument(7, new Reference($config['failure_handler']));
}
$listenerId .= '.'.$id;
@@ -164,4 +171,15 @@ protected function createListener($container, $id, $config, $userProvider)
return $listenerId;
}
+
+ public function createTargetUrlGenerator(ContainerBuilder $container, $id, $config)
+ {
+ $targetUrlGeneratorId = 'security.authentication.target_url_generator.'.$id;
+ $container
+ ->setDefinition($targetUrlGeneratorId, new DefinitionDecorator('security.authentication.target_url_generator'))
+ ->addArgument(array_intersect_key($config, $this->targetUrlGeneratorOptions))
+ ;
+
+ return $targetUrlGeneratorId;
+ }
}
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php
index 67bb0f67a3915..5fb20e0b37c42 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php
@@ -69,9 +69,9 @@ protected function createAuthProvider(ContainerBuilder $container, $id, $config,
return $provider;
}
- protected function createListener($container, $id, $config, $userProvider)
+ protected function createListener($container, $id, $config, $userProvider, $targetUrlGenerator)
{
- $listenerId = parent::createListener($container, $id, $config, $userProvider);
+ $listenerId = parent::createListener($container, $id, $config, $userProvider, $targetUrlGenerator);
if (isset($config['csrf_provider'])) {
$container
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml
index 9c1de812bc97a..e91aaee80cc56 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml
@@ -10,6 +10,7 @@
Symfony\Component\Security\Http\Firewall\ChannelListener
Symfony\Component\Security\Http\EntryPoint\FormAuthenticationEntryPoint
+ Symfony\Component\Security\Http\Authentication\TargetUrlGenerator
Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener
Symfony\Component\Security\Http\Firewall\BasicAuthenticationListener
@@ -26,7 +27,7 @@
SSL_CLIENT_S_DN
Symfony\Component\Security\Http\Firewall\AnonymousAuthenticationListener
-
+
Symfony\Component\Security\Http\Firewall\SwitchUserListener
Symfony\Component\Security\Http\Firewall\LogoutListener
@@ -44,7 +45,7 @@
Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider
SomeRandomValue
-
+
@@ -93,10 +94,13 @@
+
+
+
@@ -104,8 +108,8 @@
-
@@ -134,19 +138,19 @@
-
+
-
+
-
+
@@ -173,4 +177,4 @@
-
\ No newline at end of file
+
diff --git a/src/Symfony/Component/Security/Http/Authentication/AuthenticationSuccessHandlerInterface.php b/src/Symfony/Component/Security/Http/Authentication/AuthenticationSuccessHandlerInterface.php
index 235eb946a4db1..c9d6811ee460b 100644
--- a/src/Symfony/Component/Security/Http/Authentication/AuthenticationSuccessHandlerInterface.php
+++ b/src/Symfony/Component/Security/Http/Authentication/AuthenticationSuccessHandlerInterface.php
@@ -22,12 +22,13 @@ interface AuthenticationSuccessHandlerInterface
* is called by authentication listeners inheriting from
* AbstractAuthenticationListener.
*
- * @param EventInterface $event the "core.security" event, this event always
+ * @param EventInterface $event the "core.security" event, this event always
* has the kernel as target
- * @param Request $request
- * @param TokenInterface $token
+ * @param Request $request
+ * @param TokenInterface $token
+ * @param TargetUrlGenerator $targetUrlGenerator - has a determineTargetUrl method
*
* @return Response the response to return
*/
- function onAuthenticationSuccess(EventInterface $event, Request $request, TokenInterface $token);
-}
\ No newline at end of file
+ function onAuthenticationSuccess(EventInterface $event, Request $request, TokenInterface $token, TargetUrlGenerator $targetUrlGenerator);
+}
diff --git a/src/Symfony/Component/Security/Http/Authentication/TargetUrlGenerator.php b/src/Symfony/Component/Security/Http/Authentication/TargetUrlGenerator.php
new file mode 100644
index 0000000000000..72831c560b1c3
--- /dev/null
+++ b/src/Symfony/Component/Security/Http/Authentication/TargetUrlGenerator.php
@@ -0,0 +1,61 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Authentication;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * TargetUrlGenerator determines the authentication target url
+ *
+ * @author Fabien Potencier
+ * @author Thibault Duplessis
+ */
+class TargetUrlGenerator
+{
+ protected $options;
+
+ public function __construct($options)
+ {
+ $this->options = $options;
+ }
+
+ /**
+ * Builds the target URL according to the defined options.
+ *
+ * @param Request $request
+ *
+ * @return string
+ */
+ public function determineTargetUrl(Request $request)
+ {
+ if ($this->options['always_use_default_target_path']) {
+ return $this->options['default_target_path'];
+ }
+
+ if ($targetUrl = $request->get($this->options['target_path_parameter'])) {
+ return $targetUrl;
+ }
+
+ $session = $request->getSession();
+ if ($targetUrl = $session->get('_security.target_path')) {
+ $session->remove('_security.target_path');
+
+ return $targetUrl;
+ }
+
+ if ($this->options['use_referer'] && $targetUrl = $request->headers->get('Referer')) {
+ return $targetUrl;
+ }
+
+ return $this->options['default_target_path'];
+ }
+}
diff --git a/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php
index 353185e218cca..5e1089a96e6a1 100644
--- a/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php
@@ -15,6 +15,7 @@
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
+use Symfony\Component\Security\Http\Authentication\TargetUrlGenerator;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
@@ -50,6 +51,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
protected $securityContext;
protected $authenticationManager;
protected $sessionStrategy;
+ protected $targetUrlGenerator;
protected $providerKey;
protected $eventDispatcher;
protected $options;
@@ -66,7 +68,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
* @param array $options An array of options for the processing of a successful, or failed authentication attempt
* @param LoggerInterface $logger A LoggerInterface instance
*/
- public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null)
+ public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, TargetUrlGenerator $targetUrlGenerator, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null)
{
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
@@ -75,6 +77,7 @@ public function __construct(SecurityContextInterface $securityContext, Authentic
$this->securityContext = $securityContext;
$this->authenticationManager = $authenticationManager;
$this->sessionStrategy = $sessionStrategy;
+ $this->targetUrlGenerator = $targetUrlGenerator;
$this->providerKey = $providerKey;
$this->successHandler = $successHandler;
$this->failureHandler = $failureHandler;
@@ -226,9 +229,9 @@ protected function onSuccess(EventInterface $event, Request $request, TokenInter
}
if (null !== $this->successHandler) {
- $response = $this->successHandler->onAuthenticationSuccess($event, $request, $token);
+ $response = $this->successHandler->onAuthenticationSuccess($event, $request, $token, $this->targetUrlGenerator);
} else {
- $path = $this->determineTargetUrl($request);
+ $path = $this->targetUrlGenerator->determineTargetUrl($request);
$response = new RedirectResponse(0 !== strpos($path, 'http') ? $request->getUriForPath($path) : $path, 302);
}
@@ -239,37 +242,6 @@ protected function onSuccess(EventInterface $event, Request $request, TokenInter
return $response;
}
- /**
- * Builds the target URL according to the defined options.
- *
- * @param Request $request
- *
- * @return string
- */
- protected function determineTargetUrl(Request $request)
- {
- if ($this->options['always_use_default_target_path']) {
- return $this->options['default_target_path'];
- }
-
- if ($targetUrl = $request->get($this->options['target_path_parameter'])) {
- return $targetUrl;
- }
-
- $session = $request->getSession();
- if ($targetUrl = $session->get('_security.target_path')) {
- $session->remove('_security.target_path');
-
- return $targetUrl;
- }
-
- if ($this->options['use_referer'] && $targetUrl = $request->headers->get('Referer')) {
- return $targetUrl;
- }
-
- return $this->options['default_target_path'];
- }
-
/**
* Performs authentication.
*
diff --git a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
index d7518e6f7d7ed..f576bb1836edc 100644
--- a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
@@ -16,6 +16,7 @@
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
+use Symfony\Component\Security\Http\Authentication\TargetUrlGenerator;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
@@ -35,9 +36,9 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
/**
* {@inheritdoc}
*/
- public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null, CsrfProviderInterface $csrfProvider = null)
+ public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, TargetUrlGenerator $targetUrlGenerator, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null, CsrfProviderInterface $csrfProvider = null)
{
- parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $providerKey, array_merge(array(
+ parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $targetUrlGenerator, $providerKey, array_merge(array(
'username_parameter' => '_username',
'password_parameter' => '_password',
'csrf_parameter' => '_csrf_token',