我目前正在开发一个自定义逻辑模拟侦听器。
我覆盖了Symfony\Component\Security\Http\Firewall\SwitchUserListener,因为我想在授权切换事件之前执行对一些实体存储库(而不是用户实体)的调用:
例如,如果且仅当要模拟的用户已将权限授予请求切换的用户时,我才会授权该交换机。
是否有可能向被覆盖的侦听器注入新的参数,如规则、服务或一些数组值?
对我的自定义SwitchUserListenener的调用:
in services.yml
parameters:
security.authentication.switchuser_listener.class: acme\appBundle\EventListener\SwitchUserListener
发布于 2014-12-04 22:28:41
您的解决方案可能在这里:
Symfony定义的服务security.authentication.switchuser_listener
是一个抽象服务。它实际上不是用作侦听器的服务,但它是同一个类。
在代码中往上一点,以:
foreach ($firewalls as $name => $firewall) {
list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds);
这是您创建的防火墙的名称,可以在该防火墙上进行用户切换。
现在,您有几个选项可以覆盖侦听器。您可以继续覆盖class参数,然后像Symfony已经在做的那样操作参数:
$listener->replaceArgument(1, new Reference($userProvider));
$listener->replaceArgument(3, $id);
$listener->replaceArgument(6, $config['parameter']);
$listener->replaceArgument(7, $config['role']);
或者更简单地说,在您的扩展中编译其他方法调用。
另一种解决方案是创建一个CompilerPass
,它系统地删除原始的监听器,并用您自己的监听器取而代之。这可以在您自己的包扩展中实现,前提是它是在SecurityBundle
之后加载的。
$container->removeDefinition($id);
编辑:
另一种可能比上面更简单的解决方案是创建另一个事件侦听器。一个在请求时触发的函数。这里很重要的一点是,监听程序必须比您要覆盖的监听程序具有更高的优先级(我使用监听程序是因为可能有多个切换用户监听程序)。
棘手的部分是获取被覆盖的侦听器ID的列表,因为在侦听器实例化之后,但在它们被触发之前,您将需要遍历它们并调用您自己的方法来注入新的依赖项。
https://stackoverflow.com/questions/27296142
复制相似问题