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
++