3

我正在尝试在我的一个控制器中获取firewall信息(在 中定义)。security.yml

我需要的部分是switch_user配置:

switch_user: { role: ROLE_ADMIN, parameter: _abagnale }

目标是在管理部分创建一个链接,允许管理员一键切换用户。

第一次测试

我试图将此值定义为参数。

security:
     # ...
     switch_user: { role: %switch_user_role%, parameter: %switch_user_parameter% }

parameters:
   switch_user_role:      ROLE_ADMIN
   switch_user_parameter: _abagnale

现在在控制器中,我可以使用$this->container->parameters['switch_user_role'].

这个解决方案是不够的,因为如果我不想覆盖默认的 symfony 参数,switch_user_role并且switch_user_parameter不会被定义。

第二次测试

我尝试的另一种方法是检索代表当前防火墙的对象实例。

我发现我可以在控制器中检索防火墙名称$this->container->get('security.context')->getToken()->getProviderKey()

但我被困在这里,因为我找不到与这个值有什么关系。

那么在控制器中访问防火墙配置的最佳方法是什么?

4

1 回答 1

1

可能是简单的读取配置文件security.yml?

UPD:好的。

我认为使用 DI 是完成任务的简单方法。抱歉,我的 Symfony 2.1 代码。我无法检查它在 2.3 中是如何工作的,但我认为它没有针对此逻辑进行全局更改。

所有身份验证事件都由一些侦听器处理。例如,Symfony\Component\Security\Http\Firewall命名空间。对于 switch_user 事件,它是 Symfony\Component\Security\Http\Firewall\SwitchUserListener. 扩展它并快乐。

代码:

给定security.yml

firewalls:
    secured_area_2:
        switch_user:
            provider:             ~
            parameter:            _switch_useraaaaa
            role:                 ROLE_ALLOWED_TO_SWITCH

我创建了我的听众。

<?php

namespace Nonlux\TestBundle\Symfony;

use Symfony\Component\Security\Http\Firewall\SwitchUserListener as BaseListener;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Psr\Log\LoggerInterface;

class SwitchUserListener extends BaseListener
{
    private $usernameParameter;
    private $role;

    public function __construct(SecurityContextInterface $securityContext, UserProviderInterface $provider, UserCheckerInterface $userChecker, $providerKey, AccessDecisionManagerInterface $accessDecisionManager, LoggerInterface $logger = null, $usernameParameter = '_switch_user', $role = 'ROLE_ALLOWED_TO_SWITCH', EventDispatcherInterface $dispatcher = null)
    {
        $this->usernameParameter = $usernameParameter;
        $this->role = $role;
        parent::__construct($securityContext, $provider,$userChecker, $providerKey, $accessDecisionManager, $logger, $usernameParameter, $role, $dispatcher);

    }

    public function getUsernameParameter(){
        return $this->usernameParameter;
    }

    public function getRole(){
        return $this->role;
    }
}

我用我的改变标准听众。

# app/config/config.yml
imports:
...
    - { resource: services.xml }    
...

重要的!默认情况下,安全认证监听器有public = "false"参数。但是我们不这样做,而且我们可以在容器中看到子侦听器。如果你不喜欢这样做。您可以创建可以存储所需数据的服务,从您的侦听器中填充数据并发挥您的作用。

<!-- app/config/services.xml  -->
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">  
    <parameters>
        <parameter key="nonlux.security.authentication.switchuser_listener.class">Nonlux\TestBundle\Symfony\SwitchUserListener</parameter>
    </parameters>
    <services>
        <service id="security.authentication.switchuser_listener" class="%nonlux.security.authentication.switchuser_listener.class%" abstract="true">
            <tag name="monolog.logger" channel="security" />
            <argument type="service" id="security.context" />
            <argument /> <!-- User Provider -->
            <argument type="service" id="security.user_checker" />
            <argument /> <!--  Provider Key -->
            <argument type="service" id="security.access.decision_manager" />
            <argument type="service" id="logger" on-invalid="null" />
            <argument>_switch_user</argument>
            <argument>ROLE_ALLOWED_TO_SWITCH</argument>
            <argument type="service" id="event_dispatcher" on-invalid="null"/>
        </service>
    </services>
</container>

在控制器中使用它(使用服务'security.authentication.switchuser_listener.you_firewall_name')

<?php

namespace Nonlux\TestBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class DefaultController extends Controller
{

   /**
     * @Route("/switch", name="switch")
     * @Template()
     */
    public function switchAction()
    {
        $name=$this->get("security.authentication.switchuser_listener.secured_area_2")->getUsernameParameter();
        return array('name' => $name);
    }
}

在页面中看到魔法并感到高兴。

Hello  _switch_useraaaaa
于 2013-10-30T09:06:04.263 回答