Php 自动将投票器应用于控制器中的几种方法

Php 自动将投票器应用于控制器中的几种方法,php,symfony,authorization,symfony-3.3,Php,Symfony,Authorization,Symfony 3.3,我有一个投票者,检查用户是否可以编辑文档,规则是用户拥有文档或用户是超级管理员,要检查文档的所有权,首先必须获取文档实体。这件事我做得很顺利 但我似乎必须补充一点: $this->denyaccessunlessgrated('edit',$doc) 对于控制器中的7种方法,是否有更有效的方法 我曾想过使用内核事件,但将此检查放入事件订阅服务器并没有多大作用,因为我看不到任何影响进一步代码执行的方法。如果我抛出未捕获的异常,整个Symfony将崩溃。无论我做什么,被调用的方法都将被执行。。。但我

我有一个投票者,检查用户是否可以编辑文档,规则是用户拥有文档或用户是超级管理员,要检查文档的所有权,首先必须获取文档实体。这件事我做得很顺利

但我似乎必须补充一点:
$this->denyaccessunlessgrated('edit',$doc)
对于控制器中的7种方法,是否有更有效的方法

我曾想过使用内核事件,但将此检查放入事件订阅服务器并没有多大作用,因为我看不到任何影响进一步代码执行的方法。如果我抛出未捕获的异常,整个Symfony将崩溃。无论我做什么,被调用的方法都将被执行。。。但我还是编辑每个方法为好。
我不想到处重复这段代码,但似乎我没有其他选择。

这将取决于您从哪里获得
$doc
。您可以将注释(或
@isgrated(“do stuff with doc”)
)放在类本身上,以允许或拒绝对其中所有操作的访问(这确实假定您要保护的7个操作仅在同一个类中)

通过检查当前用户对名为“do stuff With doc”的权限的访问权限,因为这也是一个服务,它可以访问您想要注入的所有其他服务,以及将要注入适当操作的$request(通过
RequestStack$reqstack;$currRequest=$reqstack->getCurrentRequest();
)。在当前请求中是操作的参数,该参数可能包含$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);  
    }
}

显而易见的问题是,为什么只需要七种方法来编辑一个对象。似乎太过分了。更重要的是,控制器侦听器可以更改调用的控制器操作,以便可以轻松重定向被拒绝的访问,以显示“nope nope nope nope”页面或您想要的任何内容。最后,当抛出异常时,Symfony不会崩溃。看看如何处理这类事情。本文件是从商店向供应商退货的复杂过程的一部分,要完成这一过程,需要很多步骤(财务、在仓库中定位、发货、确认收到……等等)。其中一些类别经理必须审查更改,对于每个步骤都有一个操作,我们需要确保所有者或超级管理员批准该操作。我所说的崩溃是指“出现了异常”,它显示了一个错误屏幕,与界面完全不同,用户无法应对。对,但正如我给你的链接所显示的,你可以截获异常并显示你想要的任何内容。请记住,只有类别所有者甚至可以看到审查屏幕,因此任何时候访问被拒绝都必须是黑客企图。没有必要向黑客展示过于友好的界面。