2012-11-14 49 views
8

说明允许切换/只冒充向特定的用户在Symfony2中

允许用户切换到其他任何用户很容易在Symfony2中。我的问题是,如何让某个用户只能切换到某些其他用户?我使用FOSUserBundle作为我的用户提供者。

有5个用户,用户A,用户B,用户C,UserD,UserE,但其中只有3连接在一起。

用户A可以切换到用户B和用户C

用户B可以切换到用户A和用户C

用户C可以切换到UserA和用户B

感谢您的帮助!

回答

14

你可能通过重写默认SwitchUserListener实现这种类型的东西。

你会重写的参数是:security.authentication.switchuser_listener.class

例如,在parameters.yml:

parameters: 
    security.authentication.switchuser_listener.class: My\Project\Security\Listener\SwitchUserListener 

在哪里,在您的自定义监听器类,你会实现Symfony\Component\Security\Http\Firewall\ListenerInterface并使用现有的类作为您的自定义实施的基础。

+0

工程就像一个魅力。谢谢! –

2

如果你想冒充Admin用户到普通用户也有一些例子:)

https://gist.github.com/1589120

http://symfony.com/doc/current/book/security.html#impersonating-a-user

+0

据我了解,一旦用户有ROLE_ALLOWED_TO_SWITCH,他/她可以追加?_switch_user = anyusernamethatexists到的URL能够切换到该用户。如何让用户只能切换到某些其他用户? –

+0

我想这是有一些切换用户监听器。我会检查symfony的来源。 –

+0

你是否检查过源代码?感谢帮助! –

0

由于Veonik,一个(也许脏)的方式来做到这一点

添加一个角色,与语法:

ROLE_ALLOWED_TO_SWITCH_{usertype} 

例如添加ROLE_A给用户A:

ROLE_A: 
- ROLE_ALLOWED_TO_SWITCH_USERTYPEB 
- ROLE_ALLOWED_TO_SWITCH_USERTYPEC 

申报您自己在yml中的SwitchUserListener服务:

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 

在SwitchUserListener :: attemptSwitchUser方法

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; 
} 

告诉我,如果你有另一种解决方案 ++