【问题标题】:Check if a role is granted for a specific user in Symfony2 ACL检查是否为 Symfony2 ACL 中的特定用户授予角色
【发布时间】:2014-07-27 12:19:45
【问题描述】:

我想检查是否为 Symfony2 中的特定用户(不是登录的用户)授予了角色。 我知道我可以通过以下方式检查登录用户:

$securityContext = $this->get('security.context');

if (false === $securityContext->isGranted('VIEW', $objectIdentity)) {
        //do anything
}

但如果我是登录用户并且我想检查其他用户是否 isGranted ??

【问题讨论】:

    标签: symfony acl


    【解决方案1】:

    “VIEW”是一个权限,而不是一个角色。

    检查用户是否拥有权限(无论是角色还是权限)的最佳方法是访问 AccessDecisionManager。比如:

    $token = new UsernamePasswordToken($user, 'none', 'none', $user->getRoles());
    $attributes = is_array($attributes) ? $attributes : array($attributes);
    $this->get('security.access.decision_manager')->decide($token, $attributes, $object);
    

    请在此处查看原始答案:https://stackoverflow.com/a/22380765/971254 了解详情。

    【讨论】:

    • 我认为这是正确的答案。访问控制列表对于常见的用例来说太复杂了。
    【解决方案2】:

    您只需要创建一个自定义安全上下文,该上下文将获取一个用户对象并从中生成一个 UserSecurityIdentity。步骤如下:

    在 YourApp/AppBundle/Resources/config.yml 中创建一个新服务

    yourapp.security_context:
        class: YourApp\AppBundle\Security\Core\SecurityContext
        arguments: [ @security.acl.provider ]
    

    像这样创建一个自定义安全上下文类:

    namespace YourApp\AppBundle\Security\Core;
    
    use Symfony\Component\Security\Acl\Model\MutableAclProviderInterface;
    use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
    use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
    use Symfony\Component\Security\Acl\Permission\MaskBuilder;
    
    use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
    use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
    
    use YourApp\AppBundle\Document\User;
    
    /**
     * Allows ACL checking against a specific user object (regardless of whether that user is logged in or not)
     *
     */
    class SecurityContext
    {
        public function __construct(MutableAclProviderInterface $aclProvider)
        {
            $this->aclProvider = $aclProvider;
        }
    
        public function isGranted($mask, $object, User $user)
        {
            $objectIdentity = ObjectIdentity::fromDomainObject($object);
            $securityIdentity = UserSecurityIdentity::fromAccount($user);
    
            try {
                $acl = $this->aclProvider->findAcl($objectIdentity, array($securityIdentity));
            } catch (AclNotFoundException $e) {
                return false;
            }
    
            if (!is_int($mask)) {
                $builder = new MaskBuilder;
                $builder->add($mask);
    
                $mask = $builder->get();
            }
    
            try {
                return $acl->isGranted(array($mask), array($securityIdentity), false);
            } catch (NoAceFoundException $e) {
                return false;
            }
        }
    }
    

    现在您可以在需要的地方注入该服务,或者像这样从控制器中使用它:

    $someUser = $this->findSomeUserFromYourDatabase();
    
    if ($this->get('yourapp.security_context')->isGranted('VIEW', $article, $someUser) {
       // ...
    }
    

    【讨论】:

      【解决方案3】:

      无法通过SecurityContext 为其他用户检查角色,因为这将始终保存当前用户的会话令牌。例如,如果您需要检查的用户实现了UserInterface,您的任务可以通过getRoles 方法来实现。

      $otherUser = $this->get('doctrine')->...   // fetch the user
      
      if( $otherUser instanceof \Symfony\Component\Security\Core\User\UserInterface  )
      { 
           $roles = $otherUser->getRoles();
      
           // your role could be VIEW or ROLE_VIEW, check the $roles array above. 
           if ( in_array( 'VIEW' , $roles ) )
           {
            // do something else
           }
      }
      

      如果您的用户实体实现了 FosUserBundle UserInterFace,则它具有专用方法 hasRole。在这种情况下,您可以使用单线:

      $otherUser = $this->get('doctrine')->...   // fetch the user
      
      if( $otherUser instanceof \FOS\UserBundle\Model\UserInterface  )
      { 
           // your role could be VIEW or ROLE_VIEW, check the proper role names
           if ( $otherUser->hasRole( 'VIEW' ) )
           {
            // do something else
           }
      }
      

      【讨论】:

      • 不,我想要这样的东西: $user = $em->getRepository('ZxZZBundle:User')->find($id); if(false === $user->isGranted('VIEW', $objectIdentity) ) { // xxxxx } 但用户没有 isGranted 方法。
      • 我想检查他是否在特定实体上具有“VIEW”角色,例如我想检查 user3 是否可以查看 Product 实体或 user2 是否可以创建 Product 实体。
      • 您使用什么样的机制来跟踪这些 ACL 定义?
      • 注意in_array() & hasRole() 不考虑ROLE继承
      猜你喜欢
      • 2017-09-08
      • 2010-12-22
      • 2019-06-16
      • 1970-01-01
      • 2019-05-21
      • 2021-10-10
      • 1970-01-01
      • 2021-12-07
      相关资源
      最近更新 更多