Symfony 2.0, el libro oficial

13.10. Suplantando a un usuario

En ocasiones resulta útil poder cambiar de un usuario a otro sin tener que iniciar sesión de nuevo (por ejemplo, al depurar la aplicación o al tratar de encontrar un error que ve un determinado usuario y que no se puede reproducir). Para poder suplantar la identidad de otro usuario, establece la opción switch_user del firewall a true:

# app/config/security.yml
security:
    firewalls:
        main:
            # ...
            switch_user: true
<!-- app/config/security.xml -->
<config>
    <firewall>
        <!-- ... -->
        <switch-user />
    </firewall>
</config>
// app/config/security.php
$container->loadFromExtension('security', array(
    'firewalls' => array(
        'main'=> array(
            // ...
            'switch_user' => true
        ),
    ),
));

Para cambiar a otro usuario, añade en la URL de cualquier página el parámetro _switch_user y el nombre del usuario en el que te quieres convertir:

http://ejemplo.com/lo_que_sea?_switch_user=thomas

Para volver a tu usuario original, utiliza el nombre de usuario especial _exit:

http://ejemplo.com/lo_que_sea?_switch_user=_exit

Durante la suplantación, al usuario se le asigna un rol especial llamado ROLE_PREVIOUS_ADMIN. Este rol se puede utilizar por ejemplo para mostrar en la plantilla un enlace para terminar la suplantación:

{% if is_granted('ROLE_PREVIOUS_ADMIN') %}
    <a href="{{ path('homepage', {_switch_user: '_exit'}) }}">Finalizar impersonación</a>
{% endif %}
<?php if ($view['security']->isGranted('ROLE_PREVIOUS_ADMIN')): ?>
    <a href="<?php echo $view['router']->generate('homepage', array('_switch_user' => '_exit') ?>">Finalizar impersonación</a>
<?php endif; ?>

Obviamente la posibilidad de cambiarse por otro usuario debe ser de uso muy restringido. Por defecto esta opción sólo está disponible para aquellos usuarios que disponen del rol ROLE_ALLOWED_TO_SWITCH. Puedes modificar el nombre de este rol a través de la opción de configuración role. Para mayor seguridad, también puedes cambiar el nombre del parámetro que se debe añadir a la URL mediante la opción parameter:

# app/config/security.yml
security:
    firewalls:
        main:
            # ...
            switch_user: { role: ROLE_ADMIN, parameter: _want_to_be_this_user }
<!-- app/config/security.xml -->
<config>
    <firewall>
        <!-- ... -->
        <switch-user role="ROLE_ADMIN" parameter="_want_to_be_this_user" />
    </firewall>
</config>
// app/config/security.php
$container->loadFromExtension('security', array(
    'firewalls' => array(
        'main'=> array(
            ...,
            'switch_user' => array('role' => 'ROLE_ADMIN', 'parameter' => '_want_to_be_this_user'),
        ),
    ),
));