2013-07-09 5 views
6

Я расширяю обработчик ошибок аутентификации, и все работает нормально, но для одной небольшой проблемы.Переопределение обработчика отказа аутентификации - Symfony2

Это мой services.yml:

http.utils.class: 
    class: Symfony\Component\Security\Http\HttpUtils 
    auth.fail: 
    class: Acme\MyBundle\AuthenticationFailure 
    arguments: 
     - @http_kernel 
     - @http.utils.class 
     - [] 

Я поставил это использовать в security.yml:

failure_handler: auth.fail 

Это мой Acme \ MyBundle \ AuthenticationFailure.php:

namespace Acme\MyBundle; 

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\Security\Core\Exception\AuthenticationException; 
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler; 
use Symfony\Component\HttpFoundation\Response; 

class AuthenticationFailure extends DefaultAuthenticationFailureHandler 
{ 

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception) 
    { 

     //do something 

    } 

} 

Проблема в том, что параметры, установленные мной в security.yml, игнорируются. Я знаю, что третьим параметром метода _construct этого класса является массив $ options, и я не передал ничего в качестве третьего параметра (в services.yml), поэтому я предполагаю, что это проблема, и решение может будет просто передать значения в Я предполагаю, что я мог бы также сделать что-то вроде этого:.

arguments: 
    - @http_kernel 
    - @http.utils.class 
    - %security.firewalls.secure_area.form_login% 

.... Я не проверял, как проблема это жесткое кодирование, что в services.yml и это не идеально, как если бы я изменил имя secure_area, которое он сломал. Разумеется, эти ценности доступны лучше?

ответ

8

Я вижу, что вы пытаетесь передать login_path к вашей аутентификации обработчика отказов ...

... Вы должны вводить @router, адаптировать метод __construct и генерировать URL с именем маршрута (не шаблон), используемый вашим брандмауэром внутри обработчика сбоя auth. затем перенаправить пользователя туда ...

login_path: your_login_route_name # <- not a pattern like /login 

Таким образом, изменение имени брандмауэра не нарушит ваше приложение!


, если вы даже не хотите разорвать приложения при изменении названия маршрута вы можете сделать это конфигурируемый Aswell:

config.yml

parameters: 
    login.route_name: my_login_route_name 

routing.yml

%login.route_name%: 
    pattern: /login 

security.yml

security: 
    firewalls: 
     your_firewall_name: 
      failure_handler: auth.fail 
      login_path:  %login.route_name% 

услуги.YML

auth.fail: 
    arguments: 
     - # ... 
     - @router 
     - %login.route_name% 

Acme \ MyBundle \ AuthenticationFailure

use Symfony\Component\Routing\RouterInterface; 
use Symfony\Component\HttpFoundation\RedirectResponse; 

// ... 

protected $router; 

protected $loginRoute; 

public function __construct( 
    /** ... other arguments **/, 
    RouterInterface $router, 
    $loginRoute 
) 
{ 
    // .. 
    $this->router  = $router; 
    $this->loginRoute = $loginRoute; 
} 

public function onAuthenticationFailure(
    Request $request, 
    AuthenticationException $exception 
) 
{ 

    // ... 

    return new RedirectResponse($this->router->generate($this->loginRoute)); 
} 

Совет по поводу вашего предложения

(... используя что-то вроде %security.firewalls.secure_area.form_login%)

вы не можете напрямую получить доступ к конфигурации безопасности (это не параметры - вы не можете использовать %security.firewall.whatever%!) ...

по умолчанию $options передается __construct должен быть массивом ...

... так что вам может понадобиться, чтобы окружить свои передаваемые параметры, [], если эти параметры не массив.

arguments: 
    - [ %parameter1% , %parameter2% ] 
Смежные вопросы