我实现了一个自定义的Symfony2 Voter,并且会在我的控制器中将一组属性传递给denyAccessUnlessGranted
的第一个参数:
$attr = [
'module' => 'userModule'
'action' => 'edit'
];
$this->denyAccessUnlessGranted($attr, $this, 'Not authorize to edit user');
如果决策管理器方法设置为affirmative
,则此工作正常。然而,当我转向unanimous
方法时,由于我的自定义选民的设计方式,所有突然的事情都不起作用。我查看了Symfony源代码,发现原因是因为确定unanimous
方法的投票结果的方法在调用所有注册选民之前循环通过属性(而不是简单地将它们传递给选民与affirmative
和consensus
方法的情况一样。
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源代码的人。
答案 0 :(得分:1)
查看课程RoleVoter。
Voter :: Vote()返回VoterInterface :: ACCESS_GRANTED,如果任何作为参数传递的属性被授权(至少有一个允许投票)。如果有许多属性,有些属性已经授权,有些则没有 - 无论如何都会输入VoterInterface :: ACCESS_GRANTED。
但是一致投票需要每个属性被授权(没有拒绝投票);因此我们需要分别测试每个属性。