How to identify if a user is being impersonated in Symfony2?
Asked Answered
G

5

22

In an application built with Symfony2 we want superadmins to be able to impersonate other users. This is easily done by giving the superadmin user the ROLE_ALLOWED_TO_SWITCH role. The switching is implemented with a call to "somewhere?_switch_user=" as suggesed in the reference documentation.

The problem however, is to detect in a template if the current user is actually impersonated so as to print a link to "somewhere?_switch_user=_exit" on the page, thus enabling the impersonating user to return to her real user.

Guan answered 16/6, 2011 at 12:22 Comment(0)
G
31

I haven't been using Symfony2 for a while so I'm not sure, but when you switch to another user you gain all roles assigned to that user and one extra role: ROLE_PREVIOUS_ADMIN. So I guess all you need to do is to use voter to check whether such a role is assigned to the current user using voter.

// Twig

{% if is_granted('ROLE_PREVIOUS_ADMIN') %}
    <a href="...?_switch_user=_exit">EXIT</a>
{% endif %}

// PHP

<?php if ($view['security']->isGranted('ROLE_PREVIOUS_ADMIN')): ?>
    <a href="...?_switch_user=_exit">EXIT</a>
<?php endif ?>
Grayson answered 17/6, 2011 at 2:49 Comment(2)
Is there anyway to get the id of the impersonator? It would be useful for scenarios where the impersonator is making updates and we want the audit trail to recognize the original id of the impersonator.Reparative
@anushr: yes, use ?_switch_user=_exit (it exists since 2.3 at least).Turmeric
H
18

An example of how to get more details about the impersonator:

use Symfony\Component\Security\Core\Role\SwitchUserRole;


$sec = $this->get('security.context');

if($sec->isGranted('ROLE_PREVIOUS_ADMIN')) {
  foreach($sec->getToken()->getRoles() as $role) {
    if ($role instanceof SwitchUserRole) {
      $admin_user = $role->getSource()->getUser();
    }
  }
}

You then have admin_user as the original user object. Remember to use the SwitchUserRole.

Hereabout answered 1/2, 2012 at 7:33 Comment(1)
Worth noting however, if you have foreign keys on your user, security will not have the hydrated itemsBova
H
3

An example of how to display impersonator in twig:

{% if is_granted('ROLE_PREVIOUS_ADMIN') %}
  {% for role in app.security.token.roles %}
    {% if role.role == 'ROLE_PREVIOUS_ADMIN' %}
      {{ role.source.user.username }}
    {% endif %}
  {% endfor %}
{% endif %}
Huldahuldah answered 28/3, 2013 at 11:40 Comment(5)
Do you know how to do this in Symfony3? The app.security variable has been deprecated and removed, and I'm looking for an alternative now that we're updating to the most recent version.Krawczyk
@FighterJet use app.token_storage instead of app.securityHuldahuldah
app.token_storage doesn't seem to be available, according to the docs...Krawczyk
"app.token_storage.token.roles" this is not working for me. I have to check same condition {% if role.role == 'ROLE_PREVIOUS_ADMIN' %} {{ role.source.user.username }} {% endif %} Please help me how to check "ROLE_PREVIOUS_ADMIN" ?Garwin
@mobize As of Symfony 3.2 the app variable has a getToken() method so you can access the current token from twig via app.token (api.symfony.com/3.2/Symfony/Bridge/Twig/…). This is still true for the current master branch (4.2-DEV).Sacchariferous
A
0

If you need to test role from the previous admin user :

Working on Symfony 3.4

{% if is_granted('ROLE_PREVIOUS_ADMIN') %}
    {% for role in app.token.roles %}
        {% if role.role == 'ROLE_PREVIOUS_ADMIN' %}
            {% for role_from_previous in role.source.roles if role_from_previous.role == "ROLE_DELETE" %}
                {{ role.source.user.username }} has "ROLE_DELETE"
            {% endfor %}
        {% endif %}
    {% endfor %}
{% endif %}
Approach answered 26/4, 2018 at 9:53 Comment(0)
M
0

To get the original user in the controller, you can use this code:

$token = $this->container->get('security.token_storage')->getToken();
if ($token instanceof \Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken) {
    $impersonatorUser = $token->getOriginalToken()->getUser();
}
Machinegun answered 27/7, 2023 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.