I have an application in which I have a superadmin role and various user roles with different privileges. I want to be able to impersonate as any of these users using the _switch_user
query as shown on http://symfony.com/doc/current/book/security.html#impersonating-a-user
However, when I add the query to the end of my url, it doesn't seem to do anything. I've played around with this for a long time now and can't seem to find a solution. I know that the user I'm logged in as has ROLE_ALLOWED_TO_SWITCH
, but I can't quite seem to figure out how symfony does it.
I'm using a custom authentication provider so I think it has something to do with that, but I'm not sure what I need to be looking at. I can post any code needed, but I'm really not sure what to post right now.
So I dug around some more and found out that the Listener
class for my custom authentication provider was not written properly. It was written such that a new Token
was created on every page load.
Two things needed to be done as a result.
The first was to change the authentication listener to be similar to those in the Symfony Firewall Listeners, the general structure of which is shown below.
if (null !== $token = $this->securityContext->getToken()) {
if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() &&
$token->getUsername() === $username) {
return;
}
}
These listeners basically allow the authentication to proceed without creating a new token if certain conditions hold. These conditions being that the token is an instance of the right token, it's authenticated, and the username matches that of the logged in user.
Secondly, this code had to be modified to check authentication based on the original user if he tried to switch users. This issue details a similar problem someone else had. The fix was to cycle through the roles to find a SwitchUserRole
and use that data to authenticate. I've copied the patch below, which would go after the initial if
statement above.
foreach ($token->getRoles() as $role) {
if ($role instanceof SwitchUserRole) {
$token = $role->getSource();
break;
}
}
Together, the authentication listener will only create a new token if it doesn't pass certain conditions and a user who is impersonating another will have their credentials used for testing authentication instead of that of the user they're trying to impersonate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With