繁体   English   中英

覆盖复杂的Symfony2类-最佳实践

[英]Overriding a complicated Symfony2 class - best practice

我正在使用Symfony 2.3 LTS,我认为它与最新版本略有不同(针对我的问题的一部分)。

我需要重写'security.authentication.listener.form'服务,该服务是此类: https : //github.com/symfony/Security/blob/2.3/Http/Firewall/UsernamePasswordFormAuthenticationListener.php

我只想添加一点代码,没什么大不了的。

以下是重要的声明部分(在Symfony配置文件中):

    <parameter key="security.authentication.listener.form.class">Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener</parameter>

    <service id="security.authentication.listener.form"
             class="%security.authentication.listener.form.class%"
             parent="security.authentication.listener.abstract"
             abstract="true">
    </service>

    <service id="security.authentication.listener.abstract" abstract="true" public="false">
        <tag name="monolog.logger" channel="security" />
        <argument type="service" id="security.context" />
        <argument type="service" id="security.authentication.manager" />
        <argument type="service" id="security.authentication.session_strategy" />
        <argument type="service" id="security.http_utils" />
        <argument />
        <argument type="service" id="security.authentication.success_handler" />
        <argument type="service" id="security.authentication.failure_handler" />
        <argument type="collection"></argument>
        <argument type="service" id="logger" on-invalid="null" />
        <argument type="service" id="event_dispatcher" on-invalid="null" />
    </service>

另外还有两个要点:

(1) I only have experience using Yaml and although it shouldn't be difficult converting this, it does add an additional obstacle to deal with. I will also use Yaml for my finished solution. I've never seen the on-invalid attribute though for a start.
(2) I need to pass in some additional parameters of my own.

我已经尝试过重写类名和基本类扩展名,以查看它是否可以正常工作,但我不认为正在使用任何传入的值:

Yaml:

parameters:
  security.authentication.listener.form.class: MyBundle\Security\MyCustomUsernamePasswordFormAuthenticationListener

PHP类:

class MyCustomUsernamePasswordFormAuthenticationListener extends UsernamePasswordFormAuthenticationListener
{
/**
 * {@inheritdoc}
 */
public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfProviderInterface $csrfProvider = null)
{
    parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, $options, $logger, $dispatcher, $csrfProvider);
}

/**
 * {@inheritdoc}
 */
protected function attemptAuthentication(Request $request)
{
    parent::attemptAuthentication($request);
}

}

另外,我不明白为什么'security.authentication.listener.abstract'服务中的参数5为空,但如果该类为空,则该类将引发错误(但不是)。

另外,我在安全性配置( http://symfony.com/doc/2.3/reference/configuration/security.html )中没有看到security.authentication.listener.form服务作为选项的。 如果不是这样,我可以像上面提到的那样重写,但是如果可能的话,最好在security.yml中声明它。

那么在Yaml中执行此操作的最佳方法是什么? 我可以以某种方式修改,剪切和粘贴等内容,但是理想情况下,我不需要重新声明所有已声明的参数。

首先,回答为什么在安全配置( http://symfony.com/doc/2.3/reference/configuration/security.html )中看不到security.authentication.listener.form服务作为选项的原因:

  • 在app / config / security.yml中,您将找到安全捆绑包和组件的配置选项。 这些选项可以从应用程序文件夹的配置文件中进行编辑。 它们位于束,该文件夹/资源/配置内的CONFIGS,只能用一个被编辑compilerPass

现在是您的主要问题,解决方案取决于您要执行的操作:

  • 如果直接使用该类,则可能需要将其发送给装饰器,并根据需要使用该装饰器
  • 如果没有,您可以执行以下操作:在您的services.yml中添加:

     acme.security.authentication.listener.form: class: %security.authentication.listener.form.class% parent: security.authentication.listener.abstract abstract: true 

    然后在Bundle中创建一个CompilerPass并将其添加到其中:

     public function process(ContainerBuilder $container) { $definition = new DefinitionDecorator( 'acme.security.authentication.listener.form' ); $definition->setClass( 'Acme\\Bundle\\MyCustomUsernamePasswordFormAuthenticationListener' ); $definition->setAbstract( true ); // Here you can add your additional data $definition->setMethodCalls($callsArray); $container->setDefinition( 'security.authentication.listener.form', $definition ); } 

您可以覆盖security.authentication.listener.form没有compilerpass,你的资源/配置/ services.yml内,只有当你的包是SecurityBundle后启动。 但这是我不推荐的做法。 使用CompilerPass时,您将始终确保它在所有包初始化之后运行。

希望这可以帮助

暂无
暂无

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

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