有时,我有一个页面,我想要对不同规则的复杂组合做出反应,这完全相当于一件事情:‘当前用户可以这样做吗?’
目前,大多数这些检查都直接在我的控制器内,因此我需要例如:
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中复制DraftCanEditVoter逻辑,也可以在DraftCanEditVoter中实例化一个DraftEditorVoter,但这两个都不太理想,这不仅是因为代码重复的原因,也是因为我实际上有两个投票者,他们一起决定某人是否是DRAFT_EDITOR。
我也知道,我可以封装IF条件,只需制作我自己的非投票者对象,并直接使用它,但我认为这可能有点反模式。
发布于 2017-03-31 12:46:37
在我看来,你可以做两件事:
AccessDecisionManager
:http://symfony.com/doc/current/security/voters.html#checking-for-roles-inside-a-voter。我敢打赌,你可以用它来检查你的DraftEditorVoter
DraftEditorVoter
注入DraftCanEditVoter
。这样,您就可以使用它的voteOnAttribute
方法,而无需创建依赖循环。您需要调用的所有内容都已传递给您的选民,因此参数不应该是一个问题。https://stackoverflow.com/questions/43140590
复制相似问题