在Symfony选民中使用isGranted

时间:2017-03-31 12:23:14

标签: symfony security

有时候,我有一个页面,我想对不同规则的复杂组合作出反应,这完全相当于一件事:'当前用户可以这样做吗?'。

目前,大部分支票直接在我的控制器内,所以我有例如:

if($this->isGranted('DRAFT_EDITOR', $draft) && $now < $deadline && $draft->getStatus() != Draft::STATUS_FINAL) {...}

如果这些条件变得很长,并且可能最终会在整个代码中重复出现,那么所有这些都完全相同。所以我想把它们抽象成选民,这样我就可以说:

if($this->isGranted('DRAFT_CAN_EDIT') {}

那将转到一个DraftCanEdit选民,该选民将在一个地方的帖子顶部的IF语句中封装所有那些支票,并且可以轻松更改规则,使草稿可编辑,更难以意外错过某个地方的情况或混乱,并创造漏洞等。

问题在于选民无法调用isGranted(),因为它被认为是一个循环引用,只是为了向选民注入security.authorization_checker服务。

对我来说,一个选民称为isGranted似乎在语义上很好,作为一种选民继承形式,只要选民不支持它传递给isGranted的属性/主题,就不应该实际导致任何类型的循环参考问题。

当然,我可以在DraftCanEditVoter中复制DraftEditorVoter逻辑,或者我可以在DraftCanEditVoter中实例化一个DraftEditorVoter,但这些都不是理想的,不仅仅是出于代码重复的原因,还因为我实际上有两个选民一起,确定某人是否是DRAFT_EDITOR。

我也知道我可以通过制作我自己的非Voter对象并直接使用它来封装IF条件,但认为这可能有点反模式。

1 个答案:

答案 0 :(得分:2)

从我的角度来看,你可以做两件事:

  1. 我很好奇你的问题,所以我搜索了文档。这样,我就遇到了这部分文档<?php Class User{ protected $name; public function setName($name){ $this->name = $name; } public function getName(){ return $this->name; } } $arr = ["name"=>"Niklesh"]; $abc = new User; $abc->setName($arr["name"]); var_dump($abc); var_dump($abc->getName()); ?> http://symfony.com/doc/current/security/voters.html#checking-for-roles-inside-a-voter。我打赌,你可以用它来检查你的AccessDecisionManager

  2. 您可以将DraftEditorVoter注入DraftEditorVoter。这样,您可以使用其DraftCanEditVoter方法而无需创建依赖项循环。您需要调用的所有内容都已传递给您的选民,因此参数不应成为问题。