2013-07-09 41 views
6

Tôi đang mở rộng trình xử lý lỗi xác thực và mọi thứ chủ yếu hoạt động tốt, nhưng đối với một vấn đề nhỏ.Ghi đè trình xử lý sự cố xác thực - Symfony2

Đây là services.yml tôi:

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

tôi đã thiết lập này sẽ được sử dụng trong security.yml:

failure_handler: auth.fail 

Đây là Acme tôi \ 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 

    } 

} 

Vấn đề là các tùy chọn tôi đã đặt trong security.yml bị bỏ qua. Tôi biết tham số thứ ba của phương thức _construct của lớp là mảng $ options, và tôi đã không truyền bất cứ thứ gì vào như tham số thứ ba (trong services.yml), vì vậy tôi đoán đây là vấn đề và một giải pháp có thể Tôi chỉ đoán rằng tôi cũng có thể làm điều gì đó như thế này:

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

.... Tôi chưa thử nghiệm vấn đề này là khó mã hóa trong services.yml và nó không phải là lý tưởng như thể tôi đã thay đổi tên của secure_area nó sẽ phá vỡ. Chắc chắn những giá trị này có sẵn theo cách tốt hơn?

Trả lời

8

Tôi thấy bạn đang cố gắng để vượt qua login_path để xử lý thất bại xác thực của bạn ...

... bạn nên tiêm @router, điều chỉnh phương pháp __construct và tạo ra các url với tên đường (không phải là mẫu) được tường lửa của bạn sử dụng bên trong trình xử lý lỗi auth. sau đó chuyển hướng người dùng ở đó ...

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

cách này thay đổi tên tường lửa sẽ không phá vỡ ứng dụng của bạn!


nếu bạn thậm chí không muốn phá vỡ các ứng dụng khi thay đổi tên đường bạn có thể làm là tốt cấu hình này:

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% 

dịch vụ.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)); 
} 

Mẹo liên quan đến đề nghị của bạn

(... sử dụng một cái gì đó giống như %security.firewalls.secure_area.form_login%)

bạn không thể truy cập trực tiếp vào cấu hình bảo mật (đây không phải là tham số - bạn không thể sử dụng %security.firewall.whatever%!) ...

Các mặc định $options truyền cho __construct phải là một mảng ...

... vì vậy bạn có thể cần phải bao quanh các thông số bạn đã vượt qua bởi [] nếu những thông số không phải là một mảng.

arguments: 
    - [ %parameter1% , %parameter2% ] 
Các vấn đề liên quan