Jean-Luc Barat
Jean-Luc Barat

Reputation: 1165

How to impersonate user by id instead of username in symfony?

I can't figure out how to impersonate a user by user's id instead of user's username in Symfony?

The following trick which works with username can't work with id, as symfony is looking for username:

?_switch_user={id}

Upvotes: 1

Views: 1085

Answers (1)

Gerry
Gerry

Reputation: 6012

This is impossible to do without implementing your own firewall listener, as behind the scenes it loads the user from the userprovider (which only has a loadUserByUsername() method in its interface).

You could however implement your own firewall listener and get inspired by having a look at the code in Symfony\Component\Security\Http\Firewall\SwitchUserListener. For detailed information on implementing your own authentication provider, check the cookbook article.

EDIT:

One possible solution might be registering an extra request listener:

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class LookupSwitchUserListener implements EventSubscriberInterface
{
    private $repository;

    public function __construct(UserRepository $repository)
    {
        $this->repository = $repository;
    }

    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::REQUEST => ['lookup', 12] // before the firewall
        ];
    }

    public function lookup(GetResponseEvent $event)
    {
        $request = $event->getRequest();

        if ($request->has('_switch_user') {
            return; // do nothing if already a _switch_user param present
        }

        if (!$id = $request->query->has('_switch_user_by_id')) {
            return; // do nothing if no _switch_user_by_id param
        }

        // lookup $username by $id using the repository here

        $request->attributes->set('_switch_user', $username);
    }
}

Now register this listener in the service container:

services:
    my_listener:
        class: LookupSwitchUserListener
        tags:
            - { name: kernel.event_subscriber }

Calling a url with the ?_switch_user_by_id=xxx parameter should now correctly look up the username and set it so the SwitchUserListener can switch to the specified user.

Upvotes: 2

Related Questions