From 1c8c789d159ca6ce6c7791370b1da446d5c380b8 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Mon, 20 Jan 2025 10:46:39 +0100 Subject: [PATCH] [Security] Avoid refreshing user when `TokenInterface::getUser()` returns null --- .../Http/Firewall/ContextListener.php | 4 +++- .../Tests/Firewall/ContextListenerTest.php | 23 +++++++++++++++++++ .../Http/Tests/Fixtures/NullUserToken.php | 23 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Security/Http/Tests/Fixtures/NullUserToken.php diff --git a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php index e8ad79d83cd40..bc84b8cb213cf 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php @@ -191,7 +191,9 @@ public function onKernelResponse(ResponseEvent $event): void */ protected function refreshUser(TokenInterface $token): ?TokenInterface { - $user = $token->getUser(); + if (null === $user = $token->getUser()) { + return null; + } $userNotFoundByProvider = false; $userDeauthenticated = false; diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php index 8d0ab72658aff..2fd1ca6893034 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php @@ -36,6 +36,7 @@ use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Http\Firewall\ContextListener; +use Symfony\Component\Security\Http\Tests\Fixtures\NullUserToken; use Symfony\Contracts\Service\ServiceLocatorTrait; class ContextListenerTest extends TestCase @@ -58,6 +59,28 @@ public function testUserProvidersNeedToImplementAnInterface() $this->handleEventWithPreviousSession([new \stdClass()]); } + public function testTokenReturnsNullUser() + { + $tokenStorage = new TokenStorage(); + $tokenStorage->setToken(new NullUserToken()); + + $session = new Session(new MockArraySessionStorage()); + $session->set('_security_context_key', serialize($tokenStorage->getToken())); + + $request = new Request(); + $request->setSession($session); + $request->cookies->set('MOCKSESSID', true); + + $listener = new ContextListener($tokenStorage, [], 'context_key'); + $listener->authenticate(new RequestEvent( + $this->createMock(HttpKernelInterface::class), + $request, + HttpKernelInterface::MAIN_REQUEST, + )); + + $this->expectNotToPerformAssertions(); + } + public function testOnKernelResponseWillAddSession() { $session = $this->runSessionOnKernelResponse( diff --git a/src/Symfony/Component/Security/Http/Tests/Fixtures/NullUserToken.php b/src/Symfony/Component/Security/Http/Tests/Fixtures/NullUserToken.php new file mode 100644 index 0000000000000..95048e464a3f9 --- /dev/null +++ b/src/Symfony/Component/Security/Http/Tests/Fixtures/NullUserToken.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Http\Tests\Fixtures; + +use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; +use Symfony\Component\Security\Core\User\UserInterface; + +class NullUserToken extends AbstractToken +{ + public function getUser(): ?UserInterface + { + return null; + } +}