5

Tôi đang tạo REST API cho ứng dụng JS hướng của mình.Symfony2 App với xác thực RESTful, sử dụng FOSRestBundle và FOSUserBundle

Trong khi đăng nhập, biểu mẫu đăng nhập được gửi qua AJAX tới url /rest/login của API của tôi.

  • Nếu tên đăng nhập là thành công, nó sẽ trả 204
  • Nếu nó không thành công, nó sẽ trả 401

Trong khi tôi đã tách ra bức tường lửa cho các API và các ứng dụng riêng của mình, họ chia sẻ bối cảnh tương tự mà có nghĩa là, khi người dùng xác thực dựa vào API, anh ấy cũng đã được xác thực đối với ứng dụng. Vì vậy, khi máy chủ trả về 204, trang sẽ tải lại và nó sẽ chuyển hướng người dùng đến ứng dụng, bởi vì giờ đây anh ta đã đăng nhập.

Tôi đã cố gắng sử dụng trang check_login được làm sẵn của FOSUserBundle và chỉ /rest/login tại đó.

login: 
    path: /rest/login 
    defaults: 
     _controller: FOSUserBundle:Security:check 
    methods: [ POST ] 

Điều đó không hiệu quả, bởi vì nó luôn trả về chuyển hướng, bất kể điều gì. Tôi đọc tài liệu về symfony và không thể tìm thấy, cách tạo trang check_login tùy chỉnh. Những gì tôi cần là một cái gì đó như thế này

use Symfony\Component\Security\Core\Exception\AuthenticationException; 
use FOS\RestBundle\Controller\Annotations\View;  

class SecurityController { 

    /** 
    * @View(statusCode=204) 
    */ 
    public function loginAction($username, $password) { 

     /* first I need to somehow authenticate user 
      using normal authentication, that I've set up */ 
     ... 

     /* Then I need to return 204 or throw exception, 
      based on result. 
      This is done using FOSRestBundle and it's 
      listeners. */ 

     if(!$succesful) { 
      throw new AuthenticationException(); 
     } 
    } 
} 

Tôi không biết cách làm điều đó. Không có gì tôi tìm thấy trong bất kỳ tài liệu nào đã giúp tôi một chút. Tôi sẽ biết ơn vì bất kỳ gợi ý nào sẽ chỉ cho tôi đi đúng hướng.


EDIT: Để đơn giản hơn, những gì tôi đang hướng đến. Tôi muốn thông tin đăng nhập của mình hoạt động chính xác như bình thường form_login. Tôi chỉ muốn thay đổi phản hồi, nó sẽ gửi lại - thay vì chuyển hướng, tôi muốn 204 thành công và 401 bị lỗi.

Trả lời

12

Tôi đã tìm được giải pháp đơn giản. Tôi chỉ cần viết một lớp, thực hiện AuthenticationSuccessHandlerInterfaceAuthenticationFailureHandlerInterface.

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 
use Symfony\Component\Security\Core\Exception\AuthenticationException; 
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; 
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; 

class AuthenticationRestHandler implements AuthenticationSuccessHandlerInterface, AuthenticationFailureHandlerInterface { 

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { 
     return new Response('', Response::HTTP_UNAUTHORIZED); 
    } 

    public function onAuthenticationSuccess(Request $request, TokenInterface $token) { 
     return new Response('', Response::HTTP_NO_CONTENT); 
    } 
} 

Sau đó, tôi đã đăng ký dịch vụ và định cấu hình làm trình xử lý tường lửa.

services: 
    security.authentication_rest_handler: 
    class: AuthenticationRestHandler 

security: 
    firewalls: 
    rest: 
     pattern: ^rest 
     context: app 
     form_login: 
     check_path: /rest/login 
     provider: fos_userbundle 
     failure_handler: inspireon.security.authentication_rest_handler 
     success_handler: inspireon.security.authentication_rest_handler 
     username_parameter: login 
     password_parameter: password 

Vấn đề giải quyết và không cung cấp dịch vụ chứng thực phức tạp cần thiết :-)

1

Tôi hiểu vấn đề của bạn vì tôi đã vượt qua một tình huống tương tự nhưng với các dịch vụ SOAP. Ở giữa tôi có thể tái tìm kiếm trên wsse an ninh và Symfony2 đã cung cấp một giải pháp

http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html

Nó hoạt động với một mã thông báo thực tế và bạn có thể phù hợp với một người dùng trong FOSUserBundle. Chỉ nghĩ rằng tôi thấy là trường "mật khẩu" mà bạn muốn so sánh là giống nhau trong cơ sở dữ liệu (với mã hóa) thì tôi quyết định tạo một trường bổ sung chỉ cho việc sử dụng này.

Tôi hy vọng nó sẽ giúp bạn.

Chúc mừng

+0

Vì vậy, tôi cần phải thực hiện toàn bộ cung cấp dịch vụ chứng thực tùy chỉnh mới?Imo đó là một chút overkill, bởi vì tất cả tôi cần phải thay đổi là hành vi của người nghe để gửi 204/401 thay vì chuyển hướng, không phải toàn bộ quá trình. –

Các vấn đề liên quan