您的解决方案可能在这里:
https ://github.com/symfony/symfony/blob/2.6/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php#L597
security.authentication.switchuser_listener
Symfony 定义的服务是一个抽象服务。它实际上不是用作侦听器的服务,而是同一个类。
在代码中向上一点:
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);
这是您创建的可以进行用户切换的防火墙的名称。
现在您有几个选项可以覆盖侦听器。你可以继续覆盖类参数,然后像 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 的列表,因为您将需要遍历它们并调用您自己的方法来在侦听器被实例化之后但在它们触发之前注入您的新依赖项。