From 40775136ccb0301dd8216fc38be14eb6cf4949c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vasseur?= Date: Wed, 11 May 2022 14:01:36 +0200 Subject: [PATCH] Allow disabling redirect on logout --- .../Bundle/SecurityBundle/CHANGELOG.md | 1 + .../DependencyInjection/SecurityExtension.php | 10 ++++++---- .../SecurityExtensionTest.php | 19 +++++++++++++++++++ .../Security/Http/Firewall/LogoutListener.php | 7 +++---- .../Tests/Firewall/LogoutListenerTest.php | 8 +++++--- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md index 55b08604f4e41..8d0edfb709ee8 100644 --- a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md @@ -8,6 +8,7 @@ CHANGELOG * Deprecate the `Symfony\Component\Security\Core\Security` service alias, use `Symfony\Bundle\SecurityBundle\Security\Security` instead * Add `Security::getFirewallConfig()` to help to get the firewall configuration associated to the Request * Add `Security::login()` to login programmatically + * Allow disabling the redirection on successful logout by passing `null` to the `target` option 6.1 --- diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index e9432f8662933..72436414904c3 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -413,10 +413,12 @@ private function createFirewall(ContainerBuilder $container, string $id, array $ 'logout_path' => $firewall['logout']['path'], ]); - $logoutSuccessListenerId = 'security.logout.listener.default.'.$id; - $container->setDefinition($logoutSuccessListenerId, new ChildDefinition('security.logout.listener.default')) - ->replaceArgument(1, $firewall['logout']['target']) - ->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]); + if (null !== $firewall['logout']['target']) { + $logoutSuccessListenerId = 'security.logout.listener.default.'.$id; + $container->setDefinition($logoutSuccessListenerId, new ChildDefinition('security.logout.listener.default')) + ->replaceArgument(1, $firewall['logout']['target']) + ->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]); + } // add CSRF provider if (isset($firewall['logout']['csrf_token_generator'])) { diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php index 5323c16f3b2a1..cd558f3d42147 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php @@ -780,6 +780,25 @@ public function testConfigureCustomFirewallListener() $this->assertContains('custom_firewall_listener_id', $firewallListeners); } + public function testDisableLogoutTarget() + { + $container = $this->getRawContainer(); + + $container->loadFromExtension('security', [ + 'firewalls' => [ + 'main' => [ + 'logout' => [ + 'target' => null, + ], + ], + ], + ]); + + $container->compile(); + + $this->assertFalse($container->hasDefinition('security.logout.listener.default.main')); + } + protected function getRawContainer() { $container = new ContainerBuilder(); diff --git a/src/Symfony/Component/Security/Http/Firewall/LogoutListener.php b/src/Symfony/Component/Security/Http/Firewall/LogoutListener.php index f4532c60bb587..77a78929a8318 100644 --- a/src/Symfony/Component/Security/Http/Firewall/LogoutListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/LogoutListener.php @@ -87,13 +87,12 @@ public function authenticate(RequestEvent $event) $this->eventDispatcher->dispatch($logoutEvent); $response = $logoutEvent->getResponse(); - if (!$response instanceof Response) { - throw new \RuntimeException('No logout listener set the Response, make sure at least the DefaultLogoutListener is registered.'); - } $this->tokenStorage->setToken(null); - $event->setResponse($response); + if ($response) { + $event->setResponse($response); + } } /** diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php index 581ce2063e5f4..001cd35cdb577 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php @@ -122,8 +122,6 @@ public function testHandleMatchedPathWithoutCsrfValidation() public function testNoResponseSet() { - $this->expectException(\RuntimeException::class); - [$listener, , $httpUtils, $options] = $this->getListener(); $request = new Request(); @@ -133,7 +131,11 @@ public function testNoResponseSet() ->with($request, $options['logout_path']) ->willReturn(true); - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); + $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); + + $listener($event); + + $this->assertNull($event->getResponse()); } /**