为什么Symfony2 Voter一致的决策策略循环通过传递的属性?

时间:2015-06-18 13:25:38

标签: php symfony

我实现了一个自定义的Symfony2 Voter,并且会在我的控制器中将一组属性传递给denyAccessUnlessGranted的第一个参数:

$attr = [
    'module' => 'userModule'
    'action' => 'edit'
];
$this->denyAccessUnlessGranted($attr, $this, 'Not authorize to edit user');

如果决策管理器方法设置为affirmative,则此工作正常。然而,当我转向unanimous方法时,由于我的自定义选民的设计方式,所有突然的事情都不起作用。我查看了Symfony源代码,发现原因是因为确定unanimous方法的投票结果的方法在调用所有注册选民之前循环通过属性(而不是简单地将它们传递给选民与affirmativeconsensus方法的情况一样。

Symfony/Component/Security/Core/Authorization/AccessDecisionManager的摘录包含在下方:

private function decideAffirmative(TokenInterface $token, array $attributes, $object = null)
{
    $deny = 0;
    foreach ($this->voters as $voter) {
        $result = $voter->vote($token, $object, $attributes);
        ...
     }
}

private function decideConsensus(TokenInterface $token, array $attributes, $object = null)
{
    foreach ($this->voters as $voter) {
        $result = $voter->vote($token, $object, $attributes);
        ...
    }
}


private function decideUnanimous(TokenInterface $token, array $attributes, $object = null)
{
    $grant = 0;
    // ***** THIS IS THE ISSUE: WHY LOOP THROUGH THE ATTRIBUTES ****
    foreach ($attributes as $attribute) {
        foreach ($this->voters as $voter) {
            $result = $voter->vote($token, $object, array($attribute));
            ...
        }
    }
 }

unanimous决策制定的是第三个。循环遍历属性的原因是什么?这意味着我将根据我使用的策略做出重新编码我的自定义选民,我觉得这很奇怪。

PS:我的自定义选民的实施细节对这个问题并不重要,所以我决定不把它放在这里。

PS#2:这不是我的代码,这是来自Symfony2框架(https://github.com/symfony/symfony/blob/2.8/src/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.php)的代码。我只是想知道它背后的原因,以便我可以正确使用选民功能。我猜最好的人回答这个问题的人就是那些熟悉Symfony2源代码的人。

1 个答案:

答案 0 :(得分:1)

查看课程RoleVoter

Voter :: Vote()返回VoterInterface :: ACCESS_GRANTED,如果任何作为参数传递的属性被授权(至少有一个允许投票)。如果有许多属性,有些属性已经授权,有些则没有 - 无论如何都会输入VoterInterface :: ACCESS_GRANTED。

但是一致投票需要每个属性被授权(没有拒绝投票);因此我们需要分别测试每个属性。