diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterCsrfFeaturesPass.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterCsrfFeaturesPass.php index 20b79b07c49d2..c9ee463c2683c 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterCsrfFeaturesPass.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterCsrfFeaturesPass.php @@ -58,6 +58,7 @@ protected function registerLogoutHandler(ContainerBuilder $container): void $container->register('security.logout.listener.csrf_token_clearing', CsrfTokenClearingLogoutListener::class) ->addArgument(new Reference('security.csrf.token_storage')) + ->addArgument(new Reference('security.firewall.map')) ->addTag('kernel.event_subscriber'); } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/config.yml index c92abc9b88c33..29d738339119e 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/config.yml @@ -21,4 +21,3 @@ security: secret: secret logout: invalidate_session: false - stateless: true diff --git a/src/Symfony/Component/Security/Http/EventListener/CsrfTokenClearingLogoutListener.php b/src/Symfony/Component/Security/Http/EventListener/CsrfTokenClearingLogoutListener.php index ec00bc1d9be6e..7dc7ecb80e513 100644 --- a/src/Symfony/Component/Security/Http/EventListener/CsrfTokenClearingLogoutListener.php +++ b/src/Symfony/Component/Security/Http/EventListener/CsrfTokenClearingLogoutListener.php @@ -11,10 +11,12 @@ namespace Symfony\Component\Security\Http\EventListener; +use Symfony\Bundle\SecurityBundle\Security\FirewallMap; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Security\Csrf\TokenStorage\ClearableTokenStorageInterface; use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage; use Symfony\Component\Security\Http\Event\LogoutEvent; +use Symfony\Component\Security\Http\FirewallMapInterface; /** * @author Christian Flothmann @@ -24,15 +26,25 @@ class CsrfTokenClearingLogoutListener implements EventSubscriberInterface { private ClearableTokenStorageInterface $csrfTokenStorage; + private FirewallMapInterface $map; - public function __construct(ClearableTokenStorageInterface $csrfTokenStorage) + public function __construct(ClearableTokenStorageInterface $csrfTokenStorage, FirewallMapInterface $map) { $this->csrfTokenStorage = $csrfTokenStorage; + $this->map = $map; } public function onLogout(LogoutEvent $event): void { - if ($this->csrfTokenStorage instanceof SessionTokenStorage && !$event->getRequest()->hasPreviousSession()) { + $request = $event->getRequest(); + + if ( + $this->csrfTokenStorage instanceof SessionTokenStorage + && ( + ($this->map instanceof FirewallMap && $this->map->getFirewallConfig($request)->isStateless()) + || !$request->hasPreviousSession() + ) + ) { return; } diff --git a/src/Symfony/Component/Security/Http/Tests/EventListener/CsrfTokenClearingLogoutListenerTest.php b/src/Symfony/Component/Security/Http/Tests/EventListener/CsrfTokenClearingLogoutListenerTest.php index 405c7ae085510..06599416ff341 100644 --- a/src/Symfony/Component/Security/Http/Tests/EventListener/CsrfTokenClearingLogoutListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/EventListener/CsrfTokenClearingLogoutListenerTest.php @@ -12,20 +12,31 @@ namespace Symfony\Component\Security\Http\Tests\EventListener; use PHPUnit\Framework\TestCase; +use Symfony\Bundle\SecurityBundle\Security\FirewallConfig; +use Symfony\Bundle\SecurityBundle\Security\FirewallMap; use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage; use Symfony\Component\Security\Http\Event\LogoutEvent; use Symfony\Component\Security\Http\EventListener\CsrfTokenClearingLogoutListener; class CsrfTokenClearingLogoutListenerTest extends TestCase { - public function testSkipsClearingSessionTokenStorageOnStatelessRequest() + public function testSkipsClearingSessionTokenStorageOnRequestWithoutSession() { + $map = $this->createMock(FirewallMap::class); + $map + ->expects($this->once()) + ->method('getFirewallConfig') + ->willReturn(new FirewallConfig('firewall', 'user_checker')) + ; + try { (new CsrfTokenClearingLogoutListener( - new SessionTokenStorage(new RequestStack()) + new SessionTokenStorage(new RequestStack()), + $map ))->onLogout(new LogoutEvent(new Request(), null)); } catch (SessionNotFoundException) { $this->fail('clear() must not be called if the request is not associated with a session instance'); @@ -33,4 +44,34 @@ public function testSkipsClearingSessionTokenStorageOnStatelessRequest() $this->addToAssertionCount(1); } + + public function testSkipsClearingSessionTokenStorageOnStatelessRequest() + { + $session = new Session(); + + // Create a stateless request with a previous session + $request = new Request(); + $request->setSession($session); + $request->cookies->set($session->getName(), 'previous_session'); + $request->attributes->set('_stateless', true); + + $map = $this->createMock(FirewallMap::class); + $map + ->expects($this->once()) + ->method('getFirewallConfig') + ->with($this->equalTo($request)) + ->willReturn(new FirewallConfig('stateless_firewall', 'user_checker', stateless: true)) + ; + + try { + (new CsrfTokenClearingLogoutListener( + new SessionTokenStorage(new RequestStack()), + $map + ))->onLogout(new LogoutEvent($request, null)); + } catch (SessionNotFoundException) { + $this->fail('clear() must not be called if the request is stateless'); + } + + $this->addToAssertionCount(1); + } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy