Skip to content

Commit fcaf47f

Browse files
committed
[Security] Fix legacy impersonation system
When using the legacy authentication system with a user class not implementing `EquatableInterface` (for instance, the default when using Sylius) a bug prevents the impersonation system to work properly. The switch is done correctly, but then the user is disconnected on the next request because `SecurityContext::hasUserChanged()` compares the roles of the token in session with the roles of the temporary token, and they aren't equal. `ROLE_PREVIOUS_ADMIN` is added in `SwitchUserListener::attemptSwitchUser()`, but then removed if the legacy system is still enabled in `UserAuthenticationProvider`. It looks like this bug has been introduced while deprecating support for role classes: symfony/symfony@d64372d#diff-914ec544d4f7b26fda540aea3d7bc57cc5057d76bfb9ad72047d77739e3bb5a3L115 This patch fixes the issue (tested on a real Sylius project).
1 parent 4540ecb commit fcaf47f

File tree

2 files changed

+5
-1
lines changed

2 files changed

+5
-1
lines changed

Authentication/Provider/UserAuthenticationProvider.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,10 @@ public function authenticate(TokenInterface $token)
9494
}
9595

9696
if ($token instanceof SwitchUserToken) {
97-
$authenticatedToken = new SwitchUserToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles(), $token->getOriginalToken());
97+
$roles = $user->getRoles();
98+
$roles[] = 'ROLE_PREVIOUS_ADMIN';
99+
100+
$authenticatedToken = new SwitchUserToken($user, $token->getCredentials(), $this->providerKey, $roles, $token->getOriginalToken());
98101
} else {
99102
$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles());
100103
}

Tests/Authentication/Provider/UserAuthenticationProviderTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ public function testAuthenticatePreservesOriginalToken()
225225
$this->assertSame($originalToken, $authToken->getOriginalToken());
226226
$this->assertSame($user, $authToken->getUser());
227227
$this->assertContains('ROLE_FOO', $authToken->getRoleNames());
228+
$this->assertContains('ROLE_PREVIOUS_ADMIN', $authToken->getRoleNames());
228229
$this->assertEquals('foo', $authToken->getCredentials());
229230
$this->assertEquals(['foo' => 'bar'], $authToken->getAttributes(), '->authenticate() copies token attributes');
230231
}

0 commit comments

Comments
 (0)