diff options
author | Jeremy Mikola <jmikola@gmail.com> | 2011-12-30 00:08:04 -0500 |
---|---|---|
committer | Jeremy Mikola <jmikola@gmail.com> | 2012-02-14 19:03:51 -0500 |
commit | 0924bcd2ebc4ec0ad510aea6df4034bb2e716c03 (patch) | |
tree | b3a33dd65e5c9e834f41b892e98345e3088f4a7e /Http | |
parent | 5b01ebf19827e03e4f4a86efd3f69e4bb4be023a (diff) | |
download | symfony-security-0924bcd2ebc4ec0ad510aea6df4034bb2e716c03.zip symfony-security-0924bcd2ebc4ec0ad510aea6df4034bb2e716c03.tar.gz symfony-security-0924bcd2ebc4ec0ad510aea6df4034bb2e716c03.tar.bz2 |
[Security] Allow LogoutListener to validate CSRF tokens
This adds several new options to the logout listener, modeled after the form_login listener:
* csrf_parameter
* intention
* csrf_provider
The "csrf_parameter" and "intention" have default values if omitted. By default, "csrf_provider" is empty and CSRF validation is disabled in LogoutListener (preserving BC). If a service ID is given for "csrf_provider", CSRF validation will be enabled. Invalid tokens will result in an InvalidCsrfTokenException being thrown before any logout handlers are invoked.
Diffstat (limited to 'Http')
-rw-r--r-- | Http/Firewall/LogoutListener.php | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/Http/Firewall/LogoutListener.php b/Http/Firewall/LogoutListener.php index d794457..f4d0b2c 100644 --- a/Http/Firewall/LogoutListener.php +++ b/Http/Firewall/LogoutListener.php @@ -11,14 +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\InvalidCsrfTokenException; +use Symfony\Component\Security\Http\HttpUtils; +use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface; +use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface; /** * LogoutListener logout users. @@ -32,24 +33,29 @@ class LogoutListener implements ListenerInterface private $handlers; private $successHandler; private $httpUtils; + private $csrfProvider; /** * Constructor * * @param SecurityContextInterface $securityContext * @param HttpUtils $httpUtils An HttpUtilsInterface instance - * @param array $options An array of options for the processing of a logout attempt - * @param LogoutSuccessHandlerInterface $successHandler + * @param array $options An array of options to process a logout attempt + * @param LogoutSuccessHandlerInterface $successHandler A LogoutSuccessHandlerInterface instance + * @param CsrfProviderInterface $csrfProvider A CsrfProviderInterface instance */ - public function __construct(SecurityContextInterface $securityContext, HttpUtils $httpUtils, array $options = array(), LogoutSuccessHandlerInterface $successHandler = null) + public function __construct(SecurityContextInterface $securityContext, HttpUtils $httpUtils, array $options = array(), LogoutSuccessHandlerInterface $successHandler = null, CsrfProviderInterface $csrfProvider = null) { $this->securityContext = $securityContext; $this->httpUtils = $httpUtils; $this->options = array_merge(array( - 'logout_path' => '/logout', - 'target_url' => '/', + 'csrf_parameter' => '_csrf_token', + 'intention' => 'logout', + 'logout_path' => '/logout', + 'target_url' => '/', ), $options); $this->successHandler = $successHandler; + $this->csrfProvider = $csrfProvider; $this->handlers = array(); } @@ -66,7 +72,12 @@ 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) { @@ -76,6 +87,14 @@ class LogoutListener implements ListenerInterface return; } + 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 (null !== $this->successHandler) { $response = $this->successHandler->onLogoutSuccess($request); |