且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Symfony2 扩展 DefaultAuthenticationSuccessHandler

更新时间:2023-11-26 15:36:40

如果您只为应用程序定义了一个成功/失败处理程序,则有一种稍微简单的方法来执行此操作.您可以覆盖 security.authentication.success_handlersecurity.authentication.failure_handler,而不是为 success_handlerfailure_handler 定义新服务 代替.

If you only have one success / failure handler defined for your application, there's a slightly easier way to do this. Rather than define a new service for the success_handler and failure_handler, you can override security.authentication.success_handler and security.authentication.failure_handler instead.

示例:

services.yml

services.yml

services:
    security.authentication.success_handler:
        class:  StatSidekickUserBundleHandlerAuthenticationSuccessHandler
        arguments:  ["@security.http_utils", {}]
        tags:
            - { name: 'monolog.logger', channel: 'security' }

    security.authentication.failure_handler:
        class:  StatSidekickUserBundleHandlerAuthenticationFailureHandler
        arguments:  ["@http_kernel", "@security.http_utils", {}, "@logger"]
        tags:
            - { name: 'monolog.logger', channel: 'security' }

AuthenticationSuccessHandler.php

AuthenticationSuccessHandler.php

<?php
namespace StatSidekickUserBundleHandler;

use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentSecurityCoreAuthenticationTokenTokenInterface;
use SymfonyComponentSecurityHttpAuthenticationDefaultAuthenticationSuccessHandler;
use SymfonyComponentSecurityHttpHttpUtils;

class AuthenticationSuccessHandler extends DefaultAuthenticationSuccessHandler {

    public function __construct( HttpUtils $httpUtils, array $options ) {
        parent::__construct( $httpUtils, $options );
    }

    public function onAuthenticationSuccess( Request $request, TokenInterface $token ) {
        if( $request->isXmlHttpRequest() ) {
            $response = new JsonResponse( array( 'success' => true, 'username' => $token->getUsername() ) );
        } else {
            $response = parent::onAuthenticationSuccess( $request, $token );
        }
        return $response;
    }
}

AuthenticationFailureHandler.php

AuthenticationFailureHandler.php

<?php
namespace StatSidekickUserBundleHandler;

use PsrLogLoggerInterface;
use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpKernelHttpKernelInterface;
use SymfonyComponentSecurityCoreExceptionAuthenticationException;
use SymfonyComponentSecurityHttpAuthenticationDefaultAuthenticationFailureHandler;
use SymfonyComponentSecurityHttpHttpUtils;

class AuthenticationFailureHandler extends DefaultAuthenticationFailureHandler {

    public function __construct( HttpKernelInterface $httpKernel, HttpUtils $httpUtils, array $options, LoggerInterface $logger = null ) {
        parent::__construct( $httpKernel, $httpUtils, $options, $logger );
    }

    public function onAuthenticationFailure( Request $request, AuthenticationException $exception ) {
        if( $request->isXmlHttpRequest() ) {
            $response = new JsonResponse( array( 'success' => false, 'message' => $exception->getMessage() ) );
        } else {
            $response = parent::onAuthenticationFailure( $request, $exception );
        }
        return $response;
    }
}

就我而言,我只是想设置一些东西,以便在尝试使用 AJAX 进行身份验证时可以获得 JSON 响应,但原理是相同的.

In my case, I was just trying to set something up so that I could get a JSON response when I try to authenticate using AJAX, but the principle is the same.

这种方法的好处是无需任何额外工作,通常传递给默认处理程序的所有选项都应该被正确注入.这是因为 SecurityBundleDependencyInjectionSecurityFactory 在框架中的设置方式:

The benefit of this approach is that without any additional work, all of the options that are normally passed into the default handlers should get injected correctly. This happens because of how SecurityBundleDependencyInjectionSecurityFactory is setup in the framework:

protected function createAuthenticationSuccessHandler($container, $id, $config)
{
    ...
    $successHandler = $container->setDefinition($successHandlerId, new DefinitionDecorator('security.authentication.success_handler'));    
    $successHandler->replaceArgument(1, array_intersect_key($config, $this->defaultSuccessHandlerOptions));
    ...
}

protected function createAuthenticationFailureHandler($container, $id, $config)
{
    ...
    $failureHandler = $container->setDefinition($id, new DefinitionDecorator('security.authentication.failure_handler'));
    $failureHandler->replaceArgument(2, array_intersect_key($config, $this->defaultFailureHandlerOptions));
    ...
}

它专门查找 security.authentication.success_handlersecurity.authentication.failure_handler 以便将配置中的选项合并到传入的数组中.我确定有一种方法可以为您自己的服务设置类似的东西,但我还没有研究过.

It specifically looks for security.authentication.success_handler and security.authentication.failure_handler in order to merge options from your config into the arrays passed in. I'm sure there's a way to setup something similar for your own service, but I haven't looked into it yet.

希望有所帮助.