只需检查:从Symfony中投弃权票AbstractVoter isGranted

Fra*_*ank 6 php security symfony

我正在研究一个Symfony2应用程序,我们想在其中介绍Security Voters.DX计划(jay!)为我们带来了这个机制的简单版本,所以我想使用它.唯一困扰我使用\Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter的事实是,在实施抽象isGranted方法时我不能再投弃权票了.我想为我们的应用程序更改它,但从安全的角度来看,我非常感谢您对此事的看法.

需要说明的是,在我们的应用程序中,我们将使用unanimous访问决策管理器策略 - 简而言之:您至少需要一个ACCESS_GRANTED而且不需要ACCESS_DENIED- 因为我们以后可能会引入选民来禁止IP地址或其他恶作剧.

如下面的相关代码段所示,只要AbstractVoter支持属性的实现,投票将默认为Denied.

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

    // 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;
}
Run Code Online (Sandbox Code Playgroud)

我想做的是用下面的代码覆盖它

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

    $vote = self::ACCESS_ABSTAIN;

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

        // This is where we differ from SymfonyAbstractVoter. Only if there is an outspoken yes or no, a vote is cast
        // When returning null, it will still abstain
        $grant = $this->isGranted($attribute, $object, $token->getUser());
        if ($grant === true) {
            return self::ACCESS_GRANTED;
        }
        if($grant === false) {
            return self::ACCESS_DENIED;
        }

    }

    return $vote;
}
Run Code Online (Sandbox Code Playgroud)

你怎么看?ACCESS_ABSTAIN当返回null返回表单时返回是否安全isGranted并且只有一个ACCESS_GRANTED或者ACCESS_DENIED如果一个选民返回true或false?


为什么我甚至想要这样做?仍然使用AbstractVoter(因为,是的,我是一个懒惰的开发人员),但分开我的担忧.

假设我为一个帖子做了一个选民PostVoter,这将允许我编辑自己的帖子.然后会投出一个ACCESS_GRANTED.但只要我不拥有这个帖子,这个选民真的不在乎:它应该只是投了一个ACCESS_ABSTAIN.稍后它可能会碰到一个AdminVoter仍然会抛出一个ACCESS_GRANTED.unanimous然而,当使用访问决策管理器策略时,如果PostVoter已经ACCESS_DENIED投入了它,它将永远不会被任何其他选民.

我不能ACCESS_ABSTAINAbstractVoter没有覆盖vote方法的情况下将其投入现在,而在我的脑海中,更简单的选民的全部意义就是让它变得更简单:)

Ino*_*ryy 1

该类AbstractVoter是大多数用例的简单引导实现,它模拟内部 投票者的 行为方式,因此一旦您觉得您的解决方案与基本案例不同,您应该随意使用自己的方法进行覆盖。