EXPLANATION
Allowing user to switch to any other user is easy in Symfony2. My question is, how to allow certain user to switch only to certain other
If you want to impersonate Admin Users in to Regular user there are some examples :)
https://gist.github.com/1589120
http://symfony.com/doc/current/book/security.html#impersonating-a-user
You could possibly implement this type of thing by overriding the default SwitchUserListener.
The parameter you would override is: security.authentication.switchuser_listener.class
For example, in parameters.yml:
parameters:
security.authentication.switchuser_listener.class: My\Project\Security\Listener\SwitchUserListener
Where, in your custom listener class, you'd implement Symfony\Component\Security\Http\Firewall\ListenerInterface
and use the existing Symfony\Component\Security\Http\Firewall\SwitchUserListener
class as a basis for your custom implementation.
Thanks to Veonik, a (maybe dirty) way to do that
Add a role with that syntax :
ROLE_ALLOWED_TO_SWITCH_{usertype}
For example add ROLE_A to userA :
ROLE_A:
- ROLE_ALLOWED_TO_SWITCH_USERTYPEB
- ROLE_ALLOWED_TO_SWITCH_USERTYPEC
Declare your own SwitchUserListener service in yml :
security.authentication.switchuser_listener:
class: %security.authentication.switchuser_listener.class%
public: false
abstract: true
tags:
- { name: monolog.logger, channel: security}
arguments:
- @security.context
- null
- @security.user_checker
- null
- @security.access.decision_manager
- @logger
- _switch_user
- ROLE_ALLOWED_TO_SWITCH
- @event_dispatcher
- @security.role_hierarchy
In SwitchUserListener::attemptSwitchUser method
private function attemptSwitchUser(Request $request)
{
....
CODE BEFORE
....
$user = $this->provider->loadUserByUsername($username);
$rtoSwith = $this->getRolesToSwitchTo($token->getRoles());
$accessGranted = false;
foreach ($rtoSwith as $suType) {
$instance = ucfirst(strtolower($suType));
if ($user instanceof $instance) {
$accessGranted = true;
break;
}
}
if (!$accessGranted) {
throw new AccessDeniedException('Access Denied, not allowed to switch to type : '.get_class($user));
}
....
CODE AFTER
....
return $token
}
protected function getRolesToSwitchTo($roles){
$rts = array();
foreach ($this->roleHierarchy->getReachableRoles($roles) as $role) {
$tmp = explode("ROLE_ALLOWED_TO_SWITCH_", $role->getRole());
if(isset($tmp[1])){
$rts[] = $tmp[1];
}
}
return $rts;
}
Tell me if you have another solution ++