Skip to content

Commit

Permalink
[Security] Store original token in token storage when implicitly exit…
Browse files Browse the repository at this point in the history
…ing impersonation
  • Loading branch information
wouterj committed Nov 4, 2024
1 parent 8a4986d commit 7152f0e
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 2 deletions.
4 changes: 3 additions & 1 deletion Firewall/SwitchUserListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public function authenticate(RequestEvent $event)
}

if (self::EXIT_VALUE === $username) {
$this->tokenStorage->setToken($this->attemptExitUser($request));
$this->attemptExitUser($request);
} else {
try {
$this->tokenStorage->setToken($this->attemptSwitchUser($request, $username));
Expand Down Expand Up @@ -221,6 +221,8 @@ private function attemptExitUser(Request $request): TokenInterface
$original = $switchEvent->getToken();
}

$this->tokenStorage->setToken($original);

return $original;
}

Expand Down
6 changes: 5 additions & 1 deletion Tests/Firewall/SwitchUserListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
Expand Down Expand Up @@ -228,7 +229,10 @@ public function testSwitchUserAlreadySwitched()

$targetsUser = $this->callback(function ($user) { return 'kuba' === $user->getUserIdentifier(); });
$this->accessDecisionManager->expects($this->once())
->method('decide')->with($originalToken, ['ROLE_ALLOWED_TO_SWITCH'], $targetsUser)
->method('decide')->with(self::callback(function (TokenInterface $token) use ($originalToken, $tokenStorage) {
// the token storage should also contain the original token for voters depending on it
return $token === $originalToken && $tokenStorage->getToken() === $originalToken;
}), ['ROLE_ALLOWED_TO_SWITCH'], $targetsUser)
->willReturn(true);

$this->userChecker->expects($this->once())
Expand Down

0 comments on commit 7152f0e

Please sign in to comment.