10

Tôi đã xây dựng một chương trình phụ trợ API REST với Spring MVC và được bảo mật bằng Auth cơ bản với Spring Security.Gọi hàm auth cơ bản của tên miền chéo JQuery

Tôi muốn thực hiện cuộc gọi ajax miền chéo tới API REST từ các ứng dụng Javascript. Tôi không muốn sử dụng JSONP vì tôi không muốn bị giới hạn các cuộc gọi GET. Tôi sử dụng CORS và tôi đã đặt đúng tiêu đề ở phía máy chủ.

Giả sử API REST của tôi nằm trên miền localhost: 8087 và ứng dụng khách của tôi trên máy chủ cục bộ: 8086, là cuộc gọi tên miền chéo.

Trong client Javascript của tôi, tôi thực hiện cuộc gọi ajax với jQuery:

<script> 
     $.ajax ({ 
      url: "http://localhost:8087/SpringMVC/users/user1", 
      beforeSend: function (xhr) { xhr.setRequestHeader ("Authorization", "Basic xxxxxxxxxxxx"); }, 
      success: function(val) { console.log(val); alert("success" + val); }, 
      error: function(val) { console.log(val); alert("error" + val); } 
     }); 
</script> 

Vấn đề của tôi là jQuery không gửi header Authorization trong yêu cầu HTTP và tôi không biết tại sao. Tôi không hiểu vì tôi làm điều đó trong phương thức beforeSend, vì vậy nó phải nằm trong yêu cầu HTTP. Kết quả: tôi có lỗi 401.

Khi tôi thử tập lệnh từ cùng một tên miền localhost: 8087, không phải là tên miền chéo nữa, tôi không gặp vấn đề gì.

Làm cách nào có thể?

Tập lệnh của tôi chỉ là một thử nghiệm. Tôi không định đặt tên người dùng/mật khẩu của mình lên phía máy khách. Nhưng tôi muốn thử nghiệm làm thế nào để thực hiện các cuộc gọi ajax đến một API REST được bảo vệ auth cơ bản. Tôi tưởng tượng tôi phải gửi phía máy chủ để bảo mật tên người dùng/mật khẩu của mình, API REST gửi cho tôi một cookie và tôi không cần phải chuyển tên người dùng/mật khẩu nữa cho các cuộc gọi ajax tiếp theo của tôi tới API REST. Tôi có đúng không?

Tôi đã thử nghiệm API REST của mình với ứng dụng REST nâng cao của Chrome và nó hoạt động như thế. Đối với yêu cầu đầu tiên tôi cần phải vượt qua tiêu đề ủy quyền. Thế thì không cần thiết. Nó có nên hoạt động giống như vậy với trình duyệt web javascript của tôi không? Tôi định sử dụng Node.JS với Backbone để xây dựng nó.

Cảm ơn rất nhiều.

EDIT2: Dường như thực sự là vấn đề về Trình duyệt CORS. Tôi đã thêm phương thức Access-Control-Allow-Methods cho OPTIONS ở phía máy chủ và nó hoạt động trên Chrome. Tôi có quyền truy cập vào phản hồi JSON không còn lỗi nữa. Nhưng tôi vẫn cần sử dụng tiêu đề ủy quyền cho các yêu cầu tiếp theo. Làm cách nào để yêu cầu jQuery sử dụng cookie được gửi?

Và khi tôi cố gắng với Firefox 11, tôi không có quyền truy cập vào các phản ứng json và tôi có lỗi:

"NetworkError: 401 Non-Autorisé - http://localhost:8087/SpringMVC/users/user1" 
+0

Bạn có mã hóa base64 tên người dùng/mật khẩu của mình không? –

+0

Có, tôi đặt nó xxxxxxxx thay vì tên người dùng thực: mật khẩu. – rico

Trả lời

8

Rõ ràng, Chrome và Firefox trị tên miền chéo yêu cầu một chút khác nhau. Trước khi thực hiện yêu cầu miền chéo, chúng thực hiện những gì được gọi là yêu cầu 'preflight' với phương thức HTTP OPTIONS. Sự khác biệt giữa Chrome và Firefox là Chrome cũng gửi tiêu đề Cấp phép bằng thông tin xác thực trong khi Firefox thì không.

Sau đó, nó vẫn là một vấn đề cấu hình bảo mật mùa xuân. Url/người dùng/* của tôi được bảo mật cho tất cả các phương thức HTTP, bao gồm OPTIONS. Trong trường hợp Firefox, vì tiêu đề Cấp quyền không được gửi, yêu cầu của tôi không được ủy quyền. Nếu tôi hạn chế url/người dùng/* an toàn của tôi chỉ với phương thức GET, thì nó hoàn toàn hoạt động cho Firefox.Vì vậy, tôi đã phải thêm duy nhất trong bảo mật cấu hình mùa xuân của tôi:

<intercept-url pattern="https://stackoverflow.com/users/*" access="isAuthenticated()" method="GET"/> 

Sau đó, tôi có thể lựa chọn: tôi có thể thêm các phương pháp khác để được bảo đảm trong đánh chặn-url, trừ OPTIONS, hoặc tôi có thể giới hạn HTTP gọi phương thức GET trong bộ điều khiển Spring MVC của tôi, điều này thậm chí sẽ xử lý các cuộc gọi OPTIONS của tôi theo Javadoc. Tôi đã chọn giải pháp thứ hai. Nhưng nếu ai đó tìm thấy một giải pháp để buộc Firefox gửi các thông tin đăng nhập như Chrome, nó sẽ là tuyệt vời và tôi sẽ chọn cái này.

2

Một tùy chọn khác cho kịch bản cấu hình Spring An ninh được trình bày bởi rico sẽ là:

<http ... use-expressions="true"> 
    <intercept-url pattern="https://stackoverflow.com/users/*" access="permitAll" method="OPTIONS"/> 
    <intercept-url pattern="https://stackoverflow.com/users/*" access="isAuthenticated()"/> 
    ... 
</http> 

HTTP OPTIONS yêu cầu sẽ luôn luôn đi qua thẩm định và bất kỳ phương thức HTTP khác thì không.

Lưu ý thuộc tính XML use-expressions được đặt thành đúng trong thành phần <http>. Xuân An sau đó sẽ mong đợi access thuộc tính của <intercept-url> yếu tố để chứa mùa xuân EL biểu thức, như permitAllisAuthenticated().

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