繁体   English   中英

Symfony2使用参数注入模拟监听器

[英]Symfony2 impersonate listener with parameters injection

我目前正在使用自定义逻辑模拟侦听器。

我重写了Symfony \\ Component \\ Security \\ Http \\ Firewall \\ SwitchUserListener,因为在授权switch事件之前,我想对某些实体存储库(不是User实体)执行调用:

例如,当且仅当要模拟的用户已将权限授予请求切换的用户时,我才想授权切换。

是否可以向重写的侦听器注入新的参数(例如,教义服务或某些数组值)?

调用我的自定义SwitchUserListenener:

in services.yml

parameters:
    security.authentication.switchuser_listener.class: acme\appBundle\EventListener\SwitchUserListener

您的解决方案可能在这里:
https://github.com/symfony/symfony/blob/2.6/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php#L597

Symfony定义的服务security.authentication.switchuser_listener是抽象服务。 实际上,它不是用作监听器的服务,而是同一类。

在代码中向上移动以:
https://github.com/symfony/symfony/blob/2.6/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php#L233

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 ,该系统地删除原始的侦听器并将其替换为您自己的侦听CompilerPass 如果在SecurityBundle之后加载它,则可以在您自己的bundles扩展中实现。

$container->removeDefinition($id);

编辑:

也许比上面更简单的另一种解决方案是创建另一个事件侦听器。 根据要求触发的一种。 这里重要的是,侦听器必须比您要覆盖的侦听器具有更高的优先级(我使用了侦听器,因为可能有多个交换用户侦听器)。

棘手的部分是获取覆盖的侦听器ID的列表,因为您将需要遍历它们,并在实例化侦听器之后但在触发之前调用自己的方法以注入新的依赖项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM