我的问题是关于如何在已经有9个参数的SwitchUserListener中注入实体管理器。
我有一个自定义的交换机用户流,我需要在会话中设置与_switch_user参数(?_switch_user = user1&external_client_id = 1)一起传递的ExternalClient。首先,必须先从数据库中获取ExternalClient。
在我添加的parameters.yml中
security.authentication.switchuser_listener.class: App\Bundle\Listener\SwitchUserListener
对于App\Bundle\Listener\SwitchUserListener
的内容,我使用了Symfony SwitchUserListener Symfony\Component\Security\Http\Firewall\SwitchUserListener.php
一切正常,当我从侦听器中的请求变量中获取external_client_id
参数时,它将被填充。但是我似乎无法访问实体管理器。
我尝试过的事情:
在services.yml
中添加装饰器
app.decorating_switch_user:
class: App\Bundle\Listener\SwitchUserListener
decorates: security.authentication.switchuser_listener
arguments: ['@app.decorating_switch_user.inner', '@doctrine.orm.entity_manager']
public: false
覆盖services.yml
security.authentication.switchuser_listener:
abstract: true
test:
class: "%security.authentication.switchuser_listener.class%"
parent: security.authentication.switchuser_listener
public: false
# appends the '@doctrine.orm.entity_manager' argument to the parent
# argument list
arguments: ['@doctrine.orm.entity_manager']
改为收听SwitchUserEvent
app.switch_user_listener:
class: App\Bundle\Listener\SwitchUserListener
tags:
- { name: kernel.event_listener, event: security.switch_user, method: onSwitchUser }
在这里,我将“ App \ Bundle \ Listener \ SwitchUserListener”的内容替换为:
class SwitchUserListener
{
public function onSwitchUser(SwitchUserEvent $event)
{
$request = $event->getRequest();
echo "<pre>";
dump($externalClientId = $request->get('external_client_id'));
echo "</pre>";
exit;
}
}
通过这种尝试,我也获得了external_client_id,但是我不知道如何注入实体管理器。即使我这样做,也无法获得发起_switch_user请求的原始用户。 SwitchUserEvent仅有权使用 getTargetUser()
方法。
结论:
如果有人对这个主题有经验并愿意分享,那就太好了。理想情况下,我会将实体管理器服务添加到__construct函数的前9个参数中。我正在扩大课程,就像Matt在这里一样:Symfony2: Making impersonating a user more friendly
答案 0 :(得分:1)
您可以按以下说明覆盖服务。在symfony版本之间更改时,您可能需要查找/更改服务参数的具体顺序。诸如$providerKey
之类的某些参数可以留空,因为它们会由symfony自动更改/注入。
为了节省一些时间,如果您使用setter注入,则不需要重写构造函数。
看看Symfony的默认SwitchUserListener(切换到应用程序中使用的标记/版本)将有助于实现新的handle
方法。
# app/config/services.yml
services:
# [..]
security.authentication.switchuser_listener:
class: 'Your\Namespace\SwitchUserListener'
public: false
abstract: true
arguments:
- '@security.context'
- ~
- '@security.user_checker'
- ~
- '@security.access.decision_manager'
- '@?logger'
- '_switch_user'
- ~
- '@?event_dispatcher'
- ~
calls:
- [ 'setEntityManager', [ '@doctrine.orm.entity_manager' ]]
tags:
- { name: monolog.logger, channel: security }
现在您的SwitchUserListener可能看起来像这样:
namespace Your\Namespace;
use Symfony\Component\Security\Http\Firewall\SwitchUserListener as DefaultListener;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
class SwitchUserListener extends DefaultListener
{
/** @var EntityManagerInterface */
protected $em;
public function setEntityManager(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* Handles the switch to another user.
*
* @throws \LogicException if switching to a user failed
*/
public function handle(GetResponseEvent $event)
{
// Do your custom switching logic here
}
}
别忘了清除缓存!