自动将Voter应用于控制器中的几种方法

时间:2018-06-20 15:48:56

标签: php symfony authorization symfony-3.3

我有一个投票者,负责检查用户是否可以编辑文档,规则是用户拥有文档还是用户是超级管理员,以检查文档的所有权。首先必须获取实体。我做到了没有问题。

但是似乎我必须添加: $this->denyAccessUnlessGranted('edit', $doc); 控制器中大约有7种方法,是否有更有效的方法?

我考虑过使用内核事件,但是将这个检查放入事件订阅者并没有多大作用,因为我看不出有什么方法可以影响代码的进一步执行。如果我抛出未捕获的异常,整个Symfony将会崩溃。不管我做什么,都会执行被调用的方法...但是,我最好还是编辑每个方法。 我不想在任何地方重复这段代码,但似乎没有别的选择。

1 个答案:

答案 0 :(得分:0)

这取决于您在哪里获得$doc。您可以在类本身上放置一个@Security注释(或@IsGranted("do-stuff-with-doc")),以允许或拒绝访问其中的所有动作(这确实假定您只想保护7个动作)。同一班级。

使用voter,通过名为“ do-stuff-with-doc” 的权限来检查当前用户的访问权限,因为这也是一项服务,因此可以访问所有用户您希望注入的其他服务,以及将要注入到适当操作中的$ request(通过RequestStack $reqstack; $currRequest = $reqstack->getCurrentRequest();)。在current-request中是操作的参数,该参数可以包含$ doc或可能可以获取的足够信息。

由此,您可以自动连接(或手动定义以注入)选民的其他服务,这取决于您如何以及为什么用户可以访问任何东西。

class DoDocStuffVoter extends Voter
{
    public function __construct(RequestStack $reqStack)
    {
        $this->reqStack = $reqStack;
        // and other services you want to add
    }

    public function supports($attribute, $subject)
    {
        return $attribute === 'do-stuff-with-doc';
    }

    protected function voteOnAttribute($attribute, $object, TokenInterface $token): bool
    {
        $user = $token->getUser(); 
        $request = $this->reqStack->getCurrentRequest();

        dump($user, $request);
        die;

        // does someone with this request get access to doc?
        return $this->userHasAccessToDoc($user, $request);  
    }
}