diff --git a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php index 8577d5c734629..5962bf856a6d5 100644 --- a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php @@ -217,6 +217,7 @@ private function attemptExitUser(Request $request): TokenInterface if (null !== $this->dispatcher && $original->getUser() instanceof UserInterface) { $user = $this->provider->refreshUser($original->getUser()); + $original->setUser($user); $switchEvent = new SwitchUserEvent($request, $user, $original); $this->dispatcher->dispatch($switchEvent, SecurityEvents::SWITCH_USER); $original = $switchEvent->getToken(); diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php index 18e5c415d5ec4..8bc78df64a762 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php @@ -413,4 +413,34 @@ public function testSwitchUserStateless() $this->assertInstanceOf(UsernamePasswordToken::class, $this->tokenStorage->getToken()); $this->assertFalse($this->event->hasResponse()); } + + public function testSwitchUserRefreshesOriginalToken() + { + $originalUser = $this->createMock(UserInterface::class); + $refreshedOriginalUser = $this->createMock(UserInterface::class); + $this + ->userProvider + ->expects($this->any()) + ->method('refreshUser') + ->with($originalUser) + ->willReturn($refreshedOriginalUser); + $originalToken = new UsernamePasswordToken($originalUser, '', 'key'); + $this->tokenStorage->setToken(new SwitchUserToken('username', '', 'key', ['ROLE_USER'], $originalToken)); + $this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE); + + $dispatcher = $this->createMock(EventDispatcherInterface::class); + $dispatcher + ->expects($this->once()) + ->method('dispatch') + ->with( + $this->callback(function (SwitchUserEvent $event) use ($refreshedOriginalUser) { + return $event->getToken()->getUser() === $refreshedOriginalUser; + }), + SecurityEvents::SWITCH_USER + ) + ; + + $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher); + $listener($this->event); + } }