2012-08-09 100 views

回答

5

isGranted()來自安全服務獲取用戶調用isGranted(),所以這將是硬/不需要用它來獲取角色,不調整狀態的會議。

不要誤會我的意思,這是絕對有可能...這將工作,例如:

public function strangeAction() 
{ 
    // Get your User, however you normally get it 
    $user = $userRepository->find($id); 
    // Save the current token so you can put it back later 
    $previousToken = $this->get("security.context")->getToken(); 
    // Create a new token 
    $token = new UsernamePasswordToken($user, null, "main", $user->getRoles()); 
    // Update the security context with the new token 
    $this->get("security.context")->setToken($token); 
    // Now you have access to isGranted() 
    if ($this->get("security.context")->isGranted("ROLE_SOMETHING")) 
    { /* Do something here */ } 
    // Don't forget to reset the token! 
    $this->get("security.context")->setToken($previousToken); 
} 

...但真的是沒有意義的。

實際上,你不需要令牌。這樣做的更好的方法是添加一個isGranted()方法到您的用戶實體:

// Namespace\YourBundle\Entity\User.php 

class User 
{ 
    ... 
    public function isGranted($role) 
    { 
    return in_array($role, $this->getRoles()); 
    } 
    ... 
} 

現在你可以得到這些角色在你的控制器:

public function notSoStrangeAction() 
{ 
    // Get your User, however you normally get it 
    $user = $userRepository->find($id); 
    // Find out if that User has a Role associated to it 
    if ($user->isGranted("ROLE_SOMETHING")) 
    { /* Do something here */ } 
} 
+0

謝謝,它工作。然而,在你的例子中,你有一個錯字,我錯過了兩個小時:你的第一個setToken()使用$ previousToken作爲參數,而不是$ token:D – 2012-08-10 10:30:19

+0

順便說一句,這對我來說很合理,因爲user-> getRoles()不是真正的角色。我真的認爲它已經壞了,但這就是應用程序的工作原理,我不能說「嘿,讓我們改變安全防火牆!」。尤其是我實習的最後一天:p – 2012-08-10 10:33:41

+1

這個命題的問題在於它不依賴security.yml中定義的角色層次結構。查找用戶是否具有角色A與查找用戶是否被授予角色(將角色層次結構考慮在內)不一樣。後者更困難。我正在尋找這樣的解決方案... – 2013-04-12 13:09:14

3

我有同樣的要求,而前。所以我自己實現了。由於您需要容器中的層次結構信息,因此它不是 可能 建議使用此功能擴展用戶實體。

// first check if the role is inside the user roles of the user 
// if not then check for each user role if it is a master role of the check role 
public function isGranted($user, $checkrole){ 
    $userroles = $user->getRoles(); 
    if (in_array($checkrole, $userroles)){return true;} 
    foreach ($userroles as $userrole){ 
     if ($this->roleOwnsRole($userrole, $checkrole)){return true;} 
    } 
    return false; 
} 

// recursively loop over the subroles of the master to check if any of them are 
// the suggested slave role. If yes then the masterrole is a master and has 
// the same grants as the slave. 
private function roleOwnsRole($masterRole, $slaveRole, $checkvalidityroles=true, $hierarchy=null) 
{ 
    if ($hierarchy===null){$hierarchy = $this->container->getParameter('security.role_hierarchy.roles');} 
    if ($masterRole === $slaveRole){ return false; } 
    if($checkvalidityroles && (!array_key_exists($masterRole, $hierarchy) || !array_key_exists($slaveRole, $hierarchy))){ return false; } 

    $masterroles = $hierarchy[$masterRole]; 
    if(in_array($slaveRole, $masterroles)){ 
     return true; 
     }else{ 
      foreach($masterroles as $masterrolerec){ 
       if ($this->roleOwnsRole($masterrolerec, $slaveRole, false, $hierarchy)){return true;} 
      } 
      return false; 
     } 
} 
+0

注意:您可以使用@ security.role_hierarchy:getReachableRoles服務方法來解析繼承角色 – delf 2016-11-07 13:15:31

1

我認爲最好的方法是手動調用AccessDecisionManager - 像$securityContext->isGranted()確實很好,但當前登錄的用戶。如果您使用Symfony選民來確定訪問權限,這也很好。

$token = new UsernamePasswordToken($userObject, 'none', 'main', $userObject->getRoles()); 
$hasAccess = $this->get('security.access.decision_manager')->decide($token, array('voter'), $optionalObjectToCheckAccessTo); 
相關問題