summaryrefslogtreecommitdiffstats
path: root/Http
diff options
context:
space:
mode:
Diffstat (limited to 'Http')
-rw-r--r--Http/AccessMap.php2
-rw-r--r--Http/AccessMapInterface.php33
-rw-r--r--Http/Authentication/AuthenticationFailureHandlerInterface.php8
-rw-r--r--Http/Authentication/AuthenticationSuccessHandlerInterface.php8
-rw-r--r--Http/Authentication/DefaultAuthenticationFailureHandler.php87
-rw-r--r--Http/Authentication/DefaultAuthenticationSuccessHandler.php111
-rw-r--r--Http/Authorization/AccessDeniedHandlerInterface.php6
-rw-r--r--Http/Event/InteractiveLoginEvent.php16
-rw-r--r--Http/Firewall.php2
-rw-r--r--Http/Firewall/AbstractAuthenticationListener.php88
-rw-r--r--Http/Firewall/AccessListener.php4
-rw-r--r--Http/Firewall/ChannelListener.php4
-rw-r--r--Http/Firewall/ContextListener.php31
-rw-r--r--Http/Firewall/ExceptionListener.php26
-rw-r--r--Http/Firewall/LogoutListener.php72
-rw-r--r--Http/Firewall/RememberMeListener.php18
-rw-r--r--Http/Firewall/SwitchUserListener.php16
-rw-r--r--Http/Firewall/UsernamePasswordFormAuthenticationListener.php18
-rw-r--r--Http/FirewallMap.php18
-rw-r--r--Http/FirewallMapInterface.php6
-rw-r--r--Http/HttpUtils.php75
-rw-r--r--Http/Logout/CookieClearingLogoutHandler.php2
-rw-r--r--Http/Logout/DefaultLogoutSuccessHandler.php47
-rw-r--r--Http/Logout/LogoutHandlerInterface.php2
-rw-r--r--Http/Logout/LogoutSuccessHandlerInterface.php6
-rw-r--r--Http/Logout/SessionLogoutHandler.php2
-rw-r--r--Http/RememberMe/AbstractRememberMeServices.php30
-rw-r--r--Http/RememberMe/PersistentTokenBasedRememberMeServices.php20
-rw-r--r--Http/RememberMe/RememberMeServicesInterface.php4
-rw-r--r--Http/RememberMe/ResponseListener.php32
-rw-r--r--Http/RememberMe/TokenBasedRememberMeServices.php18
-rw-r--r--Http/Session/SessionAuthenticationStrategy.php6
-rw-r--r--Http/Session/SessionAuthenticationStrategyInterface.php8
33 files changed, 559 insertions, 267 deletions
diff --git a/Http/AccessMap.php b/Http/AccessMap.php
index 6d12b42..de78e15 100644
--- a/Http/AccessMap.php
+++ b/Http/AccessMap.php
@@ -20,7 +20,7 @@ use Symfony\Component\HttpFoundation\Request;
*
* @author Fabien Potencier <fabien@symfony.com>
*/
-class AccessMap
+class AccessMap implements AccessMapInterface
{
private $map = array();
diff --git a/Http/AccessMapInterface.php b/Http/AccessMapInterface.php
new file mode 100644
index 0000000..7d15fee
--- /dev/null
+++ b/Http/AccessMapInterface.php
@@ -0,0 +1,33 @@
+<?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;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * AccessMap allows configuration of different access control rules for
+ * specific parts of the website.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Kris Wallsmith <kris@symfony.com>
+ */
+interface AccessMapInterface
+{
+ /**
+ * Returns security attributes and required channel for the supplied request.
+ *
+ * @param Request $request The current request
+ *
+ * @return array A tuple of security attributes and the required channel
+ */
+ public function getPatterns(Request $request);
+}
diff --git a/Http/Authentication/AuthenticationFailureHandlerInterface.php b/Http/Authentication/AuthenticationFailureHandlerInterface.php
index 69b5426..8dbd29a 100644
--- a/Http/Authentication/AuthenticationFailureHandlerInterface.php
+++ b/Http/Authentication/AuthenticationFailureHandlerInterface.php
@@ -1,12 +1,12 @@
<?php
/*
- * This file is part of the Symfony framework.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
+ * 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;
@@ -33,7 +33,7 @@ interface AuthenticationFailureHandlerInterface
* @param Request $request
* @param AuthenticationException $exception
*
- * @return Response the response to return
+ * @return Response The response to return, never null
*/
public function onAuthenticationFailure(Request $request, AuthenticationException $exception);
}
diff --git a/Http/Authentication/AuthenticationSuccessHandlerInterface.php b/Http/Authentication/AuthenticationSuccessHandlerInterface.php
index ed44ee5..5c08e73 100644
--- a/Http/Authentication/AuthenticationSuccessHandlerInterface.php
+++ b/Http/Authentication/AuthenticationSuccessHandlerInterface.php
@@ -1,12 +1,12 @@
<?php
/*
- * This file is part of the Symfony framework.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
+ * 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;
@@ -33,7 +33,7 @@ interface AuthenticationSuccessHandlerInterface
* @param Request $request
* @param TokenInterface $token
*
- * @return Response the response to return
+ * @return Response never null
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token);
}
diff --git a/Http/Authentication/DefaultAuthenticationFailureHandler.php b/Http/Authentication/DefaultAuthenticationFailureHandler.php
new file mode 100644
index 0000000..61d77a8
--- /dev/null
+++ b/Http/Authentication/DefaultAuthenticationFailureHandler.php
@@ -0,0 +1,87 @@
+<?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\Authentication;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Http\HttpUtils;
+
+/**
+ * Class with the default authentication failure handling logic.
+ *
+ * Can be optionally be extended from by the developer to alter the behaviour
+ * while keeping the default behaviour.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Alexander <iam.asm89@gmail.com>
+ */
+class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandlerInterface
+{
+ protected $httpKernel;
+ protected $httpUtils;
+ protected $logger;
+ protected $options;
+
+ /**
+ * Constructor.
+ *
+ * @param HttpKernelInterface $httpKernel
+ * @param HttpUtils $httpUtils
+ * @param array $options Options for processing a failed authentication attempt.
+ * @param LoggerInterface $logger Optional logger
+ */
+ public function __construct(HttpKernelInterface $httpKernel, HttpUtils $httpUtils, array $options, LoggerInterface $logger = null)
+ {
+ $this->httpKernel = $httpKernel;
+ $this->httpUtils = $httpUtils;
+ $this->logger = $logger;
+
+ $this->options = array_merge(array(
+ 'failure_path' => null,
+ 'failure_forward' => false,
+ 'login_path' => '/login',
+ ), $options);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
+ {
+ if (null === $this->options['failure_path']) {
+ $this->options['failure_path'] = $this->options['login_path'];
+ }
+
+ if ($this->options['failure_forward']) {
+ if (null !== $this->logger) {
+ $this->logger->debug(sprintf('Forwarding to %s', $this->options['failure_path']));
+ }
+
+ $subRequest = $this->httpUtils->createRequest($request, $this->options['failure_path']);
+ $subRequest->attributes->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception);
+
+ return $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
+ }
+
+ if (null !== $this->logger) {
+ $this->logger->debug(sprintf('Redirecting to %s', $this->options['failure_path']));
+ }
+
+ $request->getSession()->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception);
+
+ return $this->httpUtils->createRedirectResponse($request, $this->options['failure_path']);
+ }
+}
diff --git a/Http/Authentication/DefaultAuthenticationSuccessHandler.php b/Http/Authentication/DefaultAuthenticationSuccessHandler.php
new file mode 100644
index 0000000..dc7cbe5
--- /dev/null
+++ b/Http/Authentication/DefaultAuthenticationSuccessHandler.php
@@ -0,0 +1,111 @@
+<?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\Authentication;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Http\HttpUtils;
+
+/**
+ * Class with the default authentication success handling logic.
+ *
+ * Can be optionally be extended from by the developer to alter the behaviour
+ * while keeping the default behaviour.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Alexander <iam.asm89@gmail.com>
+ */
+class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
+{
+ protected $httpUtils;
+ protected $options;
+ protected $providerKey;
+
+ /**
+ * Constructor.
+ *
+ * @param HttpUtils $httpUtils
+ * @param array $options Options for processing a successful authentication attempt.
+ */
+ public function __construct(HttpUtils $httpUtils, array $options)
+ {
+ $this->httpUtils = $httpUtils;
+
+ $this->options = array_merge(array(
+ 'always_use_default_target_path' => false,
+ 'default_target_path' => '/',
+ 'login_path' => '/login',
+ 'target_path_parameter' => '_target_path',
+ 'use_referer' => false,
+ ), $options);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function onAuthenticationSuccess(Request $request, TokenInterface $token)
+ {
+ return $this->httpUtils->createRedirectResponse($request, $this->determineTargetUrl($request));
+ }
+
+
+ /**
+ * Get the provider key.
+ *
+ * @return string
+ */
+ public function getProviderKey()
+ {
+ return $this->providerKey;
+ }
+
+ /**
+ * Set the provider key.
+ *
+ * @param string $providerKey
+ */
+ public function setProviderKey($providerKey)
+ {
+ $this->providerKey = $providerKey;
+ }
+
+ /**
+ * 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'], null, true)) {
+ return $targetUrl;
+ }
+
+ if (null !== $this->providerKey && $targetUrl = $request->getSession()->get('_security.'.$this->providerKey.'.target_path')) {
+ $request->getSession()->remove('_security.'.$this->providerKey.'.target_path');
+
+ return $targetUrl;
+ }
+
+ if ($this->options['use_referer'] && ($targetUrl = $request->headers->get('Referer')) && $targetUrl !== $this->httpUtils->generateUri($request, $this->options['login_path'])) {
+ return $targetUrl;
+ }
+
+ return $this->options['default_target_path'];
+ }
+}
diff --git a/Http/Authorization/AccessDeniedHandlerInterface.php b/Http/Authorization/AccessDeniedHandlerInterface.php
index 3811bf0..a10a5d0 100644
--- a/Http/Authorization/AccessDeniedHandlerInterface.php
+++ b/Http/Authorization/AccessDeniedHandlerInterface.php
@@ -1,12 +1,12 @@
<?php
/*
- * This file is part of the Symfony framework.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Authorization;
diff --git a/Http/Event/InteractiveLoginEvent.php b/Http/Event/InteractiveLoginEvent.php
index f242501..2225d92 100644
--- a/Http/Event/InteractiveLoginEvent.php
+++ b/Http/Event/InteractiveLoginEvent.php
@@ -21,17 +21,33 @@ class InteractiveLoginEvent extends Event
private $authenticationToken;
+ /**
+ * Constructor.
+ *
+ * @param Request $request A Request instance
+ * @param TokenInterface $authenticationToken A TokenInterface instance
+ */
public function __construct(Request $request, TokenInterface $authenticationToken)
{
$this->request = $request;
$this->authenticationToken = $authenticationToken;
}
+ /**
+ * Gets the request.
+ *
+ * @return Request A Request instance
+ */
public function getRequest()
{
return $this->request;
}
+ /**
+ * Gets the authentication token.
+ *
+ * @return TokenInterface A TokenInterface instance
+ */
public function getAuthenticationToken()
{
return $this->authenticationToken;
diff --git a/Http/Firewall.php b/Http/Firewall.php
index 91eb6a9..a590fd9 100644
--- a/Http/Firewall.php
+++ b/Http/Firewall.php
@@ -33,7 +33,7 @@ class Firewall
/**
* Constructor.
*
- * @param FirewallMap $map A FirewallMap instance
+ * @param FirewallMapInterface $map A FirewallMapInterface instance
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
*/
public function __construct(FirewallMapInterface $map, EventDispatcherInterface $dispatcher)
diff --git a/Http/Firewall/AbstractAuthenticationListener.php b/Http/Firewall/AbstractAuthenticationListener.php
index 8403ec7..410fb73 100644
--- a/Http/Firewall/AbstractAuthenticationListener.php
+++ b/Http/Firewall/AbstractAuthenticationListener.php
@@ -20,7 +20,6 @@ use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterfac
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\SessionUnavailableException;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
-use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -70,14 +69,14 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
* @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 AuthenticationSuccessHandlerInterface $successHandler
- * @param AuthenticationFailureHandlerInterface $failureHandler
- * @param LoggerInterface $logger A LoggerInterface instance
- * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
+ * @param LoggerInterface $logger A LoggerInterface instance
+ * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
*/
- public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
+ 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)
{
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
@@ -91,13 +90,6 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
$this->failureHandler = $failureHandler;
$this->options = array_merge(array(
'check_path' => '/login_check',
- 'login_path' => '/login',
- 'always_use_default_target_path' => false,
- 'default_target_path' => '/',
- 'target_path_parameter' => '_target_path',
- 'use_referer' => false,
- 'failure_path' => null,
- 'failure_forward' => false,
), $options);
$this->logger = $logger;
$this->dispatcher = $dispatcher;
@@ -133,7 +125,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
try {
if (!$request->hasPreviousSession()) {
- throw new SessionUnavailableException('Your session has timed-out, or you have disabled cookies.');
+ throw new SessionUnavailableException('Your session has timed out, or you have disabled cookies.');
}
if (null === $returnValue = $this->attemptAuthentication($request)) {
@@ -177,7 +169,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
*
* @param Request $request A Request instance
*
- * @return TokenInterface The authenticated token, or null if full authentication is not possible
+ * @return TokenInterface|Response|null The authenticated token, null if full authentication is not possible, or a Response
*
* @throws AuthenticationException if the authentication fails
*/
@@ -191,32 +183,13 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
$this->securityContext->setToken(null);
- if (null !== $this->failureHandler) {
- return $this->failureHandler->onAuthenticationFailure($request, $failed);
- }
-
- if (null === $this->options['failure_path']) {
- $this->options['failure_path'] = $this->options['login_path'];
- }
-
- if ($this->options['failure_forward']) {
- if (null !== $this->logger) {
- $this->logger->debug(sprintf('Forwarding to %s', $this->options['failure_path']));
- }
-
- $subRequest = $this->httpUtils->createRequest($request, $this->options['failure_path']);
- $subRequest->attributes->set(SecurityContextInterface::AUTHENTICATION_ERROR, $failed);
+ $response = $this->failureHandler->onAuthenticationFailure($request, $failed);
- return $event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
+ if (!$response instanceof Response) {
+ throw new \RuntimeException('Authentication Failure Handler did not return a Response.');
}
- if (null !== $this->logger) {
- $this->logger->debug(sprintf('Redirecting to %s', $this->options['failure_path']));
- }
-
- $request->getSession()->set(SecurityContextInterface::AUTHENTICATION_ERROR, $failed);
-
- return $this->httpUtils->createRedirectResponse($request, $this->options['failure_path']);
+ return $response;
}
private function onSuccess(GetResponseEvent $event, Request $request, TokenInterface $token)
@@ -236,10 +209,10 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
$this->dispatcher->dispatch(SecurityEvents::INTERACTIVE_LOGIN, $loginEvent);
}
- if (null !== $this->successHandler) {
- $response = $this->successHandler->onAuthenticationSuccess($request, $token);
- } else {
- $response = $this->httpUtils->createRedirectResponse($request, $this->determineTargetUrl($request));
+ $response = $this->successHandler->onAuthenticationSuccess($request, $token);
+
+ if (!$response instanceof Response) {
+ throw new \RuntimeException('Authentication Success Handler did not return a Response.');
}
if (null !== $this->rememberMeServices) {
@@ -248,35 +221,4 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
return $response;
}
-
- /**
- * Builds the target URL according to the defined options.
- *
- * @param Request $request
- *
- * @return string
- */
- private 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'], null, true)) {
- 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/Http/Firewall/AccessListener.php b/Http/Firewall/AccessListener.php
index 877b6c3..3e2d3a5 100644
--- a/Http/Firewall/AccessListener.php
+++ b/Http/Firewall/AccessListener.php
@@ -13,7 +13,7 @@ namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
-use Symfony\Component\Security\Http\AccessMap;
+use Symfony\Component\Security\Http\AccessMapInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -33,7 +33,7 @@ class AccessListener implements ListenerInterface
private $authManager;
private $logger;
- public function __construct(SecurityContextInterface $context, AccessDecisionManagerInterface $accessDecisionManager, AccessMap $map, AuthenticationManagerInterface $authManager, LoggerInterface $logger = null)
+ public function __construct(SecurityContextInterface $context, AccessDecisionManagerInterface $accessDecisionManager, AccessMapInterface $map, AuthenticationManagerInterface $authManager, LoggerInterface $logger = null)
{
$this->context = $context;
$this->accessDecisionManager = $accessDecisionManager;
diff --git a/Http/Firewall/ChannelListener.php b/Http/Firewall/ChannelListener.php
index 847753f..9b0f8c6 100644
--- a/Http/Firewall/ChannelListener.php
+++ b/Http/Firewall/ChannelListener.php
@@ -11,7 +11,7 @@
namespace Symfony\Component\Security\Http\Firewall;
-use Symfony\Component\Security\Http\AccessMap;
+use Symfony\Component\Security\Http\AccessMapInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -28,7 +28,7 @@ class ChannelListener implements ListenerInterface
private $authenticationEntryPoint;
private $logger;
- public function __construct(AccessMap $map, AuthenticationEntryPointInterface $authenticationEntryPoint, LoggerInterface $logger = null)
+ public function __construct(AccessMapInterface $map, AuthenticationEntryPointInterface $authenticationEntryPoint, LoggerInterface $logger = null)
{
$this->map = $map;
$this->authenticationEntryPoint = $authenticationEntryPoint;
diff --git a/Http/Firewall/ContextListener.php b/Http/Firewall/ContextListener.php
index 0bf5cff..fddd3c7 100644
--- a/Http/Firewall/ContextListener.php
+++ b/Http/Firewall/ContextListener.php
@@ -22,6 +22,7 @@ use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
@@ -36,6 +37,7 @@ class ContextListener implements ListenerInterface
private $contextKey;
private $logger;
private $userProviders;
+ private $dispatcher;
public function __construct(SecurityContextInterface $context, array $userProviders, $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
{
@@ -43,14 +45,17 @@ class ContextListener implements ListenerInterface
throw new \InvalidArgumentException('$contextKey must not be empty.');
}
+ foreach ($userProviders as $userProvider) {
+ if (!$userProvider instanceof UserProviderInterface) {
+ throw new \InvalidArgumentException(sprintf('User provider "%s" must implement "Symfony\Component\Security\Core\User\UserProviderInterface".', get_class($userProvider)));
+ }
+ }
+
$this->context = $context;
$this->userProviders = $userProviders;
$this->contextKey = $contextKey;
$this->logger = $logger;
-
- if (null !== $dispatcher) {
- $dispatcher->addListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
- }
+ $this->dispatcher = $dispatcher;
}
/**
@@ -60,6 +65,10 @@ class ContextListener implements ListenerInterface
*/
public function handle(GetResponseEvent $event)
{
+ if (null !== $this->dispatcher && HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
+ $this->dispatcher->addListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
+ }
+
$request = $event->getRequest();
$session = $request->hasPreviousSession() ? $request->getSession() : null;
@@ -104,19 +113,19 @@ class ContextListener implements ListenerInterface
return;
}
- if (null === $token = $this->context->getToken()) {
- return;
+ if (null !== $this->logger) {
+ $this->logger->debug('Write SecurityContext in the session');
}
- if (null === $token || $token instanceof AnonymousToken) {
+ if (null === $session = $event->getRequest()->getSession()) {
return;
}
- if (null !== $this->logger) {
- $this->logger->debug('Write SecurityContext in the session');
+ if ((null === $token = $this->context->getToken()) || ($token instanceof AnonymousToken)) {
+ $session->remove('_security_'.$this->contextKey);
+ } else {
+ $session->set('_security_'.$this->contextKey, serialize($token));
}
-
- $event->getRequest()->getSession()->set('_security_'.$this->contextKey, serialize($token));
}
/**
diff --git a/Http/Firewall/ExceptionListener.php b/Http/Firewall/ExceptionListener.php
index b704262..f134f9c 100644
--- a/Http/Firewall/ExceptionListener.php
+++ b/Http/Firewall/ExceptionListener.php
@@ -15,12 +15,12 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
-use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Core\Exception\AccountStatusException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\InsufficientAuthenticationException;
+use Symfony\Component\Security\Core\Exception\LogoutException;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
@@ -39,6 +39,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class ExceptionListener
{
private $context;
+ private $providerKey;
private $accessDeniedHandler;
private $authenticationEntryPoint;
private $authenticationTrustResolver;
@@ -46,11 +47,12 @@ class ExceptionListener
private $logger;
private $httpUtils;
- public function __construct(SecurityContextInterface $context, AuthenticationTrustResolverInterface $trustResolver, HttpUtils $httpUtils, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null, LoggerInterface $logger = null)
+ public function __construct(SecurityContextInterface $context, AuthenticationTrustResolverInterface $trustResolver, HttpUtils $httpUtils, $providerKey, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null, LoggerInterface $logger = null)
{
$this->context = $context;
$this->accessDeniedHandler = $accessDeniedHandler;
$this->httpUtils = $httpUtils;
+ $this->providerKey = $providerKey;
$this->authenticationEntryPoint = $authenticationEntryPoint;
$this->authenticationTrustResolver = $trustResolver;
$this->errorPage = $errorPage;
@@ -95,10 +97,12 @@ class ExceptionListener
return;
}
} elseif ($exception instanceof AccessDeniedException) {
+ $event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
+
$token = $this->context->getToken();
if (!$this->authenticationTrustResolver->isFullFledged($token)) {
if (null !== $this->logger) {
- $this->logger->debug('Access denied (user is not fully authenticated); redirecting to authentication entry point');
+ $this->logger->debug(sprintf('Access is denied (user is not fully authenticated) by "%s" at line %s; redirecting to authentication entry point', $exception->getFile(), $exception->getLine()));
}
try {
@@ -110,7 +114,7 @@ class ExceptionListener
}
} else {
if (null !== $this->logger) {
- $this->logger->debug('Access is denied (and user is neither anonymous, nor remember-me)');
+ $this->logger->debug(sprintf('Access is denied (and user is neither anonymous, nor remember-me) by "%s" at line %s', $exception->getFile(), $exception->getLine()));
}
try {
@@ -125,10 +129,7 @@ class ExceptionListener
$subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception);
$response = $event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
- $response->setStatusCode(403);
} else {
- $event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
-
return;
}
} catch (\Exception $e) {
@@ -141,6 +142,12 @@ class ExceptionListener
return;
}
}
+ } elseif ($exception instanceof LogoutException) {
+ if (null !== $this->logger) {
+ $this->logger->info(sprintf('Logout exception occurred; wrapping with AccessDeniedHttpException (%s)', $exception->getMessage()));
+ }
+
+ return;
} else {
return;
}
@@ -160,10 +167,9 @@ class ExceptionListener
$this->setTargetPath($request);
- if ($authException instanceof AccountStatusException && ($token = $this->context->getToken()) instanceof UsernamePasswordToken) {
+ if ($authException instanceof AccountStatusException) {
// remove the security token to prevent infinite redirect loops
$this->context->setToken(null);
- $request->getSession()->remove('_security_'.$token->getProviderKey());
}
return $this->authenticationEntryPoint->start($request, $authException);
@@ -173,7 +179,7 @@ class ExceptionListener
{
// session isn't required when using http basic authentication mechanism for example
if ($request->hasSession() && $request->isMethodSafe()) {
- $request->getSession()->set('_security.target_path', $request->getUri());
+ $request->getSession()->set('_security.' . $this->providerKey . '.target_path', $request->getUri());
}
}
}
diff --git a/Http/Firewall/LogoutListener.php b/Http/Firewall/LogoutListener.php
index 07244f5..32a0511 100644
--- a/Http/Firewall/LogoutListener.php
+++ b/Http/Firewall/LogoutListener.php
@@ -11,13 +11,15 @@
namespace Symfony\Component\Security\Http\Firewall;
-use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
-
-use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
-use Symfony\Component\Security\Core\SecurityContextInterface;
-use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
+use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Core\Exception\LogoutException;
+use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
+use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
/**
* LogoutListener logout users.
@@ -27,28 +29,32 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent;
class LogoutListener implements ListenerInterface
{
private $securityContext;
- private $logoutPath;
- private $targetUrl;
+ private $options;
private $handlers;
private $successHandler;
private $httpUtils;
+ private $csrfProvider;
/**
* Constructor
*
* @param SecurityContextInterface $securityContext
* @param HttpUtils $httpUtils An HttpUtilsInterface instance
- * @param string $logoutPath The path that starts the logout process
- * @param string $targetUrl The URL to redirect to after logout
- * @param LogoutSuccessHandlerInterface $successHandler
+ * @param LogoutSuccessHandlerInterface $successHandler A LogoutSuccessHandlerInterface instance
+ * @param array $options An array of options to process a logout attempt
+ * @param CsrfProviderInterface $csrfProvider A CsrfProviderInterface instance
*/
- public function __construct(SecurityContextInterface $securityContext, HttpUtils $httpUtils, $logoutPath, $targetUrl = '/', LogoutSuccessHandlerInterface $successHandler = null)
+ public function __construct(SecurityContextInterface $securityContext, HttpUtils $httpUtils, LogoutSuccessHandlerInterface $successHandler, array $options = array(), CsrfProviderInterface $csrfProvider = null)
{
$this->securityContext = $securityContext;
$this->httpUtils = $httpUtils;
- $this->logoutPath = $logoutPath;
- $this->targetUrl = $targetUrl;
+ $this->options = array_merge(array(
+ 'csrf_parameter' => '_csrf_token',
+ 'intention' => 'logout',
+ 'logout_path' => '/logout',
+ ), $options);
$this->successHandler = $successHandler;
+ $this->csrfProvider = $csrfProvider;
$this->handlers = array();
}
@@ -56,8 +62,6 @@ class LogoutListener implements ListenerInterface
* Adds a logout handler
*
* @param LogoutHandlerInterface $handler
- *
- * @return void
*/
public function addHandler(LogoutHandlerInterface $handler)
{
@@ -67,24 +71,32 @@ class LogoutListener implements ListenerInterface
/**
* Performs the logout if requested
*
+ * If a CsrfProviderInterface instance is available, it will be used to
+ * validate the request.
+ *
* @param GetResponseEvent $event A GetResponseEvent instance
+ * @throws InvalidCsrfTokenException if the CSRF token is invalid
+ * @throws RuntimeException if the LogoutSuccessHandlerInterface instance does not return a response
*/
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
- if (!$this->httpUtils->checkRequestPath($request, $this->logoutPath)) {
+ if (!$this->requiresLogout($request)) {
return;
}
- if (null !== $this->successHandler) {
- $response = $this->successHandler->onLogoutSuccess($request);
+ if (null !== $this->csrfProvider) {
+ $csrfToken = $request->get($this->options['csrf_parameter'], null, true);
- if (!$response instanceof Response) {
- throw new \RuntimeException('Logout Success Handler did not return a Response.');
+ if (false === $this->csrfProvider->isCsrfTokenValid($this->options['intention'], $csrfToken)) {
+ throw new LogoutException('Invalid CSRF token.');
}
- } else {
- $response = $this->httpUtils->createRedirectResponse($request, $this->targetUrl);
+ }
+
+ $response = $this->successHandler->onLogoutSuccess($request);
+ if (!$response instanceof Response) {
+ throw new \RuntimeException('Logout Success Handler did not return a Response.');
}
// handle multiple logout attempts gracefully
@@ -98,4 +110,20 @@ class LogoutListener implements ListenerInterface
$event->setResponse($response);
}
+
+ /**
+ * Whether this request is asking for logout.
+ *
+ * The default implementation only processed requests to a specific path,
+ * but a subclass could change this to logout requests where
+ * certain parameters is present.
+ *
+ * @param Request $request
+ *
+ * @return Boolean
+ */
+ protected function requiresLogout(Request $request)
+ {
+ return $this->httpUtils->checkRequestPath($request, $this->options['logout_path']);
+ }
}
diff --git a/Http/Firewall/RememberMeListener.php b/Http/Firewall/RememberMeListener.php
index ccda113..3614f79 100644
--- a/Http/Firewall/RememberMeListener.php
+++ b/Http/Firewall/RememberMeListener.php
@@ -1,5 +1,14 @@
<?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\HttpKernel\Log\LoggerInterface;
@@ -12,15 +21,6 @@ use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-/*
- * This file is part of the Symfony framework.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
-
/**
* RememberMeListener implements authentication capabilities via a cookie
*
diff --git a/Http/Firewall/SwitchUserListener.php b/Http/Firewall/SwitchUserListener.php
index 9780860..7f0aa78 100644
--- a/Http/Firewall/SwitchUserListener.php
+++ b/Http/Firewall/SwitchUserListener.php
@@ -86,9 +86,7 @@ class SwitchUserListener implements ListenerInterface
try {
$this->securityContext->setToken($this->attemptSwitchUser($request));
} catch (AuthenticationException $e) {
- if (null !== $this->logger) {
- $this->logger->warn(sprintf('Switch User failed: "%s"', $e->getMessage()));
- }
+ throw new \LogicException(sprintf('Switch User failed: "%s"', $e->getMessage()));
}
}
@@ -108,8 +106,14 @@ class SwitchUserListener implements ListenerInterface
private function attemptSwitchUser(Request $request)
{
$token = $this->securityContext->getToken();
- if (false !== $this->getOriginalToken($token)) {
- throw new \LogicException(sprintf('You are already switched to "%s" user.', $token->getUsername()));
+ $originalToken = $this->getOriginalToken($token);
+
+ if (false !== $originalToken) {
+ if ($token->getUsername() === $request->get($this->usernameParameter)) {
+ return $token;
+ } else {
+ throw new \LogicException(sprintf('You are already switched to "%s" user.', $token->getUsername()));
+ }
}
if (false === $this->accessDecisionManager->decide($token, array($this->role))) {
@@ -148,7 +152,7 @@ class SwitchUserListener implements ListenerInterface
private function attemptExitUser(Request $request)
{
if (false === $original = $this->getOriginalToken($this->securityContext->getToken())) {
- throw new AuthenticationCredentialsNotFoundException(sprintf('Could not find original Token object.'));
+ throw new AuthenticationCredentialsNotFoundException('Could not find original Token object.');
}
if (null !== $this->dispatcher) {
diff --git a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
index bd2cec1..22330a8 100644
--- a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
+++ b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
@@ -37,15 +37,15 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
/**
* {@inheritdoc}
*/
- public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfProviderInterface $csrfProvider = null)
+ 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)
{
- parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, array_merge(array(
+ parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge(array(
'username_parameter' => '_username',
'password_parameter' => '_password',
'csrf_parameter' => '_csrf_token',
'intention' => 'authenticate',
'post_only' => true,
- ), $options), $successHandler, $failureHandler, $logger, $dispatcher);
+ ), $options), $logger, $dispatcher);
$this->csrfProvider = $csrfProvider;
}
@@ -53,6 +53,18 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
/**
* {@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 ($this->options['post_only'] && 'post' !== strtolower($request->getMethod())) {
diff --git a/Http/FirewallMap.php b/Http/FirewallMap.php
index d5fc331..dfc0984 100644
--- a/Http/FirewallMap.php
+++ b/Http/FirewallMap.php
@@ -1,20 +1,20 @@
<?php
-namespace Symfony\Component\Security\Http;
-
-use Symfony\Component\HttpFoundation\RequestMatcherInterface;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\Security\Http\Firewall\ExceptionListener;
-
/*
- * This file is part of the Symfony framework.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
*/
+namespace Symfony\Component\Security\Http;
+
+use Symfony\Component\HttpFoundation\RequestMatcherInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Http\Firewall\ExceptionListener;
+
/**
* FirewallMap allows configuration of different firewalls for specific parts
* of the website.
diff --git a/Http/FirewallMapInterface.php b/Http/FirewallMapInterface.php
index 57afc75..336125f 100644
--- a/Http/FirewallMapInterface.php
+++ b/Http/FirewallMapInterface.php
@@ -1,12 +1,12 @@
<?php
/*
- * This file is part of the Symfony framework.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http;
diff --git a/Http/HttpUtils.php b/Http/HttpUtils.php
index cac130e..76cfc6a 100644
--- a/Http/HttpUtils.php
+++ b/Http/HttpUtils.php
@@ -15,7 +15,8 @@ use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
-use Symfony\Component\Routing\RouterInterface;
+use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
@@ -26,16 +27,19 @@ use Symfony\Component\Routing\Exception\ResourceNotFoundException;
*/
class HttpUtils
{
- private $router;
+ private $urlGenerator;
+ private $urlMatcher;
/**
* Constructor.
*
- * @param RouterInterface $router An RouterInterface instance
+ * @param UrlGeneratorInterface $urlGenerator A UrlGeneratorInterface instance
+ * @param UrlMatcherInterface $urlMatcher A UrlMatcherInterface instance
*/
- public function __construct(RouterInterface $router = null)
+ public function __construct(UrlGeneratorInterface $urlGenerator = null, UrlMatcherInterface $urlMatcher = null)
{
- $this->router = $router;
+ $this->urlGenerator = $urlGenerator;
+ $this->urlMatcher = $urlMatcher;
}
/**
@@ -49,14 +53,7 @@ class HttpUtils
*/
public function createRedirectResponse(Request $request, $path, $status = 302)
{
- if ('/' === $path[0]) {
- $path = $request->getUriForPath($path);
- } elseif (0 !== strpos($path, 'http')) {
- $this->resetLocale($request);
- $path = $this->generateUrl($path, true);
- }
-
- return new RedirectResponse($path, $status);
+ return new RedirectResponse($this->generateUri($request, $path), $status);
}
/**
@@ -69,15 +66,7 @@ class HttpUtils
*/
public function createRequest(Request $request, $path)
{
- if ($path && '/' !== $path[0] && 0 !== strpos($path, 'http')) {
- $this->resetLocale($request);
- $path = $this->generateUrl($path, true);
- }
- if (0 !== strpos($path, 'http')) {
- $path = $request->getUriForPath($path);
- }
-
- $newRequest = Request::create($path, 'get', array(), $request->cookies->all(), array(), $request->server->all());
+ $newRequest = Request::create($this->generateUri($request, $path), 'get', array(), $request->cookies->all(), array(), $request->server->all());
if ($session = $request->getSession()) {
$newRequest->setSession($session);
}
@@ -99,7 +88,7 @@ class HttpUtils
* Checks that a given path matches the Request.
*
* @param Request $request A Request instance
- * @param string $path A path (an absolute path (/foo) or a route name (foo))
+ * @param string $path A path (an absolute path (/foo), an absolute URL (http://...), or a route name (foo))
*
* @return Boolean true if the path is the same as the one from the Request, false otherwise
*/
@@ -107,7 +96,7 @@ class HttpUtils
{
if ('/' !== $path[0]) {
try {
- $parameters = $this->router->match($request->getPathInfo());
+ $parameters = $this->urlMatcher->match($request->getPathInfo());
return $path === $parameters['_route'];
} catch (MethodNotAllowedException $e) {
@@ -117,36 +106,36 @@ class HttpUtils
}
}
- return $path === $request->getPathInfo();
+ return $path === rawurldecode($request->getPathInfo());
}
- // hack (don't have a better solution for now)
- private function resetLocale(Request $request)
+ /**
+ * Generates a URI, based on the given path or absolute URL.
+ *
+ * @param Request $request A Request instance
+ * @param string $path A path (an absolute path (/foo), an absolute URL (http://...), or a route name (foo))
+ *
+ * @return string An absolute URL
+ */
+ public function generateUri($request, $path)
{
- $context = $this->router->getContext();
- if ($context->getParameter('_locale')) {
- return;
+ if (0 === strpos($path, 'http') || !$path) {
+ return $path;
}
- try {
- $parameters = $this->router->match($request->getPathInfo());
-
- if (isset($parameters['_locale'])) {
- $context->setParameter('_locale', $parameters['_locale']);
- } elseif ($session = $request->getSession()) {
- $context->setParameter('_locale', $session->getLocale());
- }
- } catch (\Exception $e) {
- // let's hope user doesn't use the locale in the path
+ if ('/' === $path[0]) {
+ return $request->getUriForPath($path);
}
+
+ return $this->generateUrl($path, true);
}
private function generateUrl($route, $absolute = false)
{
- if (null === $this->router) {
- throw new \LogicException('You must provide a RouterInterface instance to be able to use routes.');
+ if (null === $this->urlGenerator) {
+ throw new \LogicException('You must provide a UrlGeneratorInterface instance to be able to use routes.');
}
- return $this->router->generate($route, array(), $absolute);
+ return $this->urlGenerator->generate($route, array(), $absolute);
}
}
diff --git a/Http/Logout/CookieClearingLogoutHandler.php b/Http/Logout/CookieClearingLogoutHandler.php
index ddb24e3..6838be5 100644
--- a/Http/Logout/CookieClearingLogoutHandler.php
+++ b/Http/Logout/CookieClearingLogoutHandler.php
@@ -40,8 +40,6 @@ class CookieClearingLogoutHandler implements LogoutHandlerInterface
* @param Request $request
* @param Response $response
* @param TokenInterface $token
- *
- * @return void
*/
public function logout(Request $request, Response $response, TokenInterface $token)
{
diff --git a/Http/Logout/DefaultLogoutSuccessHandler.php b/Http/Logout/DefaultLogoutSuccessHandler.php
new file mode 100644
index 0000000..e06cb6d
--- /dev/null
+++ b/Http/Logout/DefaultLogoutSuccessHandler.php
@@ -0,0 +1,47 @@
+<?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\Logout;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
+
+/**
+ * Default logout success handler will redirect users to a configured path.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
+ */
+class DefaultLogoutSuccessHandler implements LogoutSuccessHandlerInterface
+{
+ protected $httpUtils;
+ protected $targetUrl;
+
+ /**
+ * @param HttpUtils $httpUtils
+ * @param string $targetUrl
+ */
+ public function __construct(HttpUtils $httpUtils, $targetUrl = '/')
+ {
+ $this->httpUtils = $httpUtils;
+
+ $this->targetUrl = $targetUrl;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function onLogoutSuccess(Request $request)
+ {
+ return $this->httpUtils->createRedirectResponse($request, $this->targetUrl);
+ }
+}
diff --git a/Http/Logout/LogoutHandlerInterface.php b/Http/Logout/LogoutHandlerInterface.php
index 6780e4d..5e1cea8 100644
--- a/Http/Logout/LogoutHandlerInterface.php
+++ b/Http/Logout/LogoutHandlerInterface.php
@@ -30,8 +30,6 @@ interface LogoutHandlerInterface
* @param Request $request
* @param Response $response
* @param TokenInterface $token
- *
- * @return void
*/
public function logout(Request $request, Response $response, TokenInterface $token);
}
diff --git a/Http/Logout/LogoutSuccessHandlerInterface.php b/Http/Logout/LogoutSuccessHandlerInterface.php
index ad878e6..61642a8 100644
--- a/Http/Logout/LogoutSuccessHandlerInterface.php
+++ b/Http/Logout/LogoutSuccessHandlerInterface.php
@@ -1,12 +1,12 @@
<?php
/*
- * This file is part of the Symfony framework.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Logout;
diff --git a/Http/Logout/SessionLogoutHandler.php b/Http/Logout/SessionLogoutHandler.php
index 0a7e5cd..e91cf17 100644
--- a/Http/Logout/SessionLogoutHandler.php
+++ b/Http/Logout/SessionLogoutHandler.php
@@ -28,8 +28,6 @@ class SessionLogoutHandler implements LogoutHandlerInterface
* @param Request $request
* @param Response $response
* @param TokenInterface $token
- *
- * @return void
*/
public function logout(Request $request, Response $response, TokenInterface $token)
{
diff --git a/Http/RememberMe/AbstractRememberMeServices.php b/Http/RememberMe/AbstractRememberMeServices.php
index 92472ee..4f7c5b9 100644
--- a/Http/RememberMe/AbstractRememberMeServices.php
+++ b/Http/RememberMe/AbstractRememberMeServices.php
@@ -1,5 +1,14 @@
<?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\RememberMe;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
@@ -15,15 +24,6 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
-/*
- * 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.
- */
-
/**
* Base class implementing the RememberMeServicesInterface
*
@@ -144,8 +144,6 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* @param Request $request
* @param Response $response
* @param TokenInterface $token
- *
- * @return void
*/
public function logout(Request $request, Response $response, TokenInterface $token)
{
@@ -157,8 +155,6 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* an attempted authentication fails.
*
* @param Request $request
- *
- * @return void
*/
final public function loginFail(Request $request)
{
@@ -173,8 +169,6 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* @param Request $request
* @param Response $response
* @param TokenInterface $token The token that resulted in a successful authentication
- *
- * @return void
*/
final public function loginSuccess(Request $request, Response $response, TokenInterface $token)
{
@@ -224,8 +218,6 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* @param Request $request
* @param Response $response
* @param TokenInterface $token
- *
- * @return void
*/
abstract protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token);
@@ -268,8 +260,6 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* Deletes the remember-me cookie
*
* @param Request $request
- *
- * @return void
*/
protected function cancelCookie(Request $request)
{
@@ -293,7 +283,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
return true;
}
- $parameter = $request->request->get($this->options['remember_me_parameter'], null, true);
+ $parameter = $request->get($this->options['remember_me_parameter'], null, true);
if ($parameter === null && null !== $this->logger) {
$this->logger->debug(sprintf('Did not send remember-me cookie (remember-me parameter "%s" was not sent).', $this->options['remember_me_parameter']));
diff --git a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
index e9d22ba..8944672 100644
--- a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
+++ b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
@@ -1,5 +1,14 @@
<?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\RememberMe;
use Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface;
@@ -11,15 +20,6 @@ use Symfony\Component\Security\Core\Exception\CookieTheftException;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-/*
- * 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.
- */
-
/**
* Concrete implementation of the RememberMeServicesInterface which needs
* an implementation of TokenProviderInterface for providing remember-me
@@ -35,8 +35,6 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
* Sets the token provider
*
* @param TokenProviderInterface $tokenProvider
- *
- * @return void
*/
public function setTokenProvider(TokenProviderInterface $tokenProvider)
{
diff --git a/Http/RememberMe/RememberMeServicesInterface.php b/Http/RememberMe/RememberMeServicesInterface.php
index 116a6b1..a00dcef 100644
--- a/Http/RememberMe/RememberMeServicesInterface.php
+++ b/Http/RememberMe/RememberMeServicesInterface.php
@@ -60,8 +60,6 @@ interface RememberMeServicesInterface
* This method needs to take care of invalidating the cookie.
*
* @param Request $request
- *
- * @return void
*/
public function loginFail(Request $request);
@@ -79,8 +77,6 @@ interface RememberMeServicesInterface
* @param Request $request
* @param Response $response
* @param TokenInterface $token
- *
- * @return void
*/
public function loginSuccess(Request $request, Response $response, TokenInterface $token);
}
diff --git a/Http/RememberMe/ResponseListener.php b/Http/RememberMe/ResponseListener.php
new file mode 100644
index 0000000..6cbdcb3
--- /dev/null
+++ b/Http/RememberMe/ResponseListener.php
@@ -0,0 +1,32 @@
+<?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\RememberMe;
+
+use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
+
+/**
+ * Adds remember-me cookies to the Response.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ResponseListener
+{
+ public function onKernelResponse(FilterResponseEvent $event)
+ {
+ $request = $event->getRequest();
+ $response = $event->getResponse();
+
+ if ($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME)) {
+ $response->headers->setCookie($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME));
+ }
+ }
+}
diff --git a/Http/RememberMe/TokenBasedRememberMeServices.php b/Http/RememberMe/TokenBasedRememberMeServices.php
index aa76228..bd828f2 100644
--- a/Http/RememberMe/TokenBasedRememberMeServices.php
+++ b/Http/RememberMe/TokenBasedRememberMeServices.php
@@ -1,14 +1,5 @@
<?php
-namespace Symfony\Component\Security\Http\RememberMe;
-
-use Symfony\Component\HttpFoundation\Cookie;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-use Symfony\Component\Security\Core\Exception\AuthenticationException;
-use Symfony\Component\Security\Core\User\UserInterface;
-
/*
* This file is part of the Symfony package.
*
@@ -18,6 +9,15 @@ use Symfony\Component\Security\Core\User\UserInterface;
* file that was distributed with this source code.
*/
+namespace Symfony\Component\Security\Http\RememberMe;
+
+use Symfony\Component\HttpFoundation\Cookie;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\User\UserInterface;
+
/**
* Concrete implementation of the RememberMeServicesInterface providing
* remember-me capabilities without requiring a TokenProvider.
diff --git a/Http/Session/SessionAuthenticationStrategy.php b/Http/Session/SessionAuthenticationStrategy.php
index 7e0c20a..e9c9826 100644
--- a/Http/Session/SessionAuthenticationStrategy.php
+++ b/Http/Session/SessionAuthenticationStrategy.php
@@ -1,12 +1,12 @@
<?php
/*
- * This file is part of the Symfony framework.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Session;
diff --git a/Http/Session/SessionAuthenticationStrategyInterface.php b/Http/Session/SessionAuthenticationStrategyInterface.php
index 38dc343..2bc292b 100644
--- a/Http/Session/SessionAuthenticationStrategyInterface.php
+++ b/Http/Session/SessionAuthenticationStrategyInterface.php
@@ -1,12 +1,12 @@
<?php
/*
- * This file is part of the Symfony framework.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Session;
@@ -32,8 +32,6 @@ interface SessionAuthenticationStrategyInterface
*
* @param Request $request
* @param TokenInterface $token
- *
- * @return void
*/
public function onAuthentication(Request $request, TokenInterface $token);
}