我正在研究一个我们想要介绍Security Voters的Symfony2应用程序。 DX计划(jay!)给我们the simpler version这个机制,所以我想用它。唯一困扰我使用\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;
}
我想要做的是使用下面的代码覆盖
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;
}
你怎么看?从ACCESS_ABSTAIN
返回null时返回isGranted
是否安全,如果投票人返回true或false,则只投出ACCESS_GRANTED
或ACCESS_DENIED
?
为什么我甚至想要这样做?仍然使用AbstractVoter
(因为,是的,我是一个懒惰的开发人员),但我分开了我的顾虑。
让我们说我为一个帖子PostVoter
做了一个选民,这将允许我编辑自己的帖子。然后它将投射ACCESS_GRANTED
。但只要我不拥有这个帖子,这个选民真的不在乎:它应该只投一个ACCESS_ABSTAIN
。
稍后它可能会遇到AdminVoter
,但仍然会投放ACCESS_GRANTED
。
但是,在使用unanimous
访问权限决策经理策略时,如果此PostVoter
已经投放了ACCESS_DENIED
,那么它将永远不会获得任何其他选民。
我现在无法在ACCESS_ABSTAIN
中投放AbstractVoter
vote
而不会覆盖{{1}}方法,而在我看来,更简单的选民的全部观点就是制作它更简单:)