Symfony选民:我如何检查用户的角色?

时间:2015-07-18 02:17:09

标签: php symfony

我拥有特定用户拥有的帖子。我创建了一个选民来检查用户是否拥有帖子,但我也希望管理员(即ROLE_ADMIN及以上)能够访问所有帖子。

我已按照How to Use Voters to Check User Permissions食谱条目中的说明(并且几乎复制了代码)。现在我想知道我是如何进行检查的。思路:

  1. 将另一项服务传递给选民......不确定是哪一项。
  2. 使用vote方法执行某些操作。
  3. 不要在选民中进行检查,但要在控制人员内部进行检查(即,如果他们是管理员,请不要给选民打电话。)

1 个答案:

答案 0 :(得分:2)

这就是我想出的。基本上覆盖了父vote()方法,添加了对其中角色的检查。角色检查对我有点担心,因为它没有使用任何内置方法,但我不确定它们是否可以访问并且它不会创建循环(因为角色)检查也使用选民)。我已经标记了自定义的部分。

如果有什么不重要的话,请告诉我。

<?php
// src/AppBundle/Security/Authorization/Voter/PostVoter.php

namespace AppBundle\Security\Authorization\Voter;

use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

class PostVoter extends AbstractVoter
{
    const VIEW = 'view';
    const EDIT = 'edit';

    /**
     * {@inheritDoc}
     */
    public function vote(TokenInterface $token, $object, array $attributes)
    {
        if (!$object || !$this->supportsClass(get_class($object))) {
            return self::ACCESS_ABSTAIN;
        }

        // ----------------------------------
        // -- start – custom
        $user = $token->getUser();
        if ($user instanceof UserInterface) {
            if (in_array('ROLE_SUPER_ADMIN', $user->getRoles())) {
                return self::ACCESS_GRANTED;
            }
        }
        // -- end – custom
        // ----------------------------------

        // abstain vote by default in case none of the attributes are supported
        $vote = self::ACCESS_ABSTAIN;

        foreach ($attributes as $attribute) {
            if (!$this->supportsAttribute($attribute)) {
                continue;
            }

            // as soon as at least one attribute is supported, default is to deny access
            $vote = self::ACCESS_DENIED;

            if ($this->isGranted($attribute, $object, $token->getUser())) {
                // grant access as soon as at least one voter returns a positive response
                return self::ACCESS_GRANTED;
            }
        }

        return $vote;
    }

    // ----------------------------------
    // -- start – custom
    protected function isGranted($attribute, $post, $user = null)
    {
        switch($attribute) {
            case self::VIEW:
                if ($post->getIsActive()) {
                    return true;
                }
                break;

            // must be owned by the current user or the user must be a super admin
            case self::EDIT:
                // make sure there is a user object (i.e. that the user is logged in)
                if (!$user instanceof UserInterface) {
                    return false;
                }

                if ($user->getId() === $post->getOwner()->getId()) {
                    return true;
                }
                break;
        }

        return false;
    }
    // -- end – custom
    // ----------------------------------

    protected function getSupportedAttributes()
    {
        return array(self::VIEW, self::EDIT);
    }

    protected function getSupportedClasses()
    {
        return array('AppBundle\Entity\Post');
    }

}