2009-01-19 12 views
67

Tôi hiện đang làm việc trên thư viện REST cho .net và tôi muốn nghe một số ý kiến ​​về điểm mở mà tôi có: REST và xác thực.Biến thể REST và xác thực

Dưới đây là một ví dụ về một giao diện RESTful sử dụng với thư viện:

[RestRoot("/user")] 
public interface IUserInterface 
{ 
    [RestPut("/")] 
    void Add(User user); 

    [RestGet("/")] 
    int[] List(); 

    [RestGet("/get/{id}")] 
    User Get(int id); 

    [RestDelete("/delete/{id}")] 
    void Delete(int id); 
} 

Mã máy chủ sau đó chỉ cần thực hiện giao diện và các khách hàng có thể có được cùng một giao diện thông qua một nhà máy. Hoặc nếu khách hàng không sử dụng thư viện, yêu cầu HTTP tiêu chuẩn cũng hoạt động.

Tôi biết rằng có nhiều cách chính để sử dụng Xác thực cơ bản HTTP hoặc gửi mã thông báo cho các yêu cầu yêu cầu người dùng được xác thực.

Phương pháp đầu tiên (HTTP Basic Auth), có các vấn đề sau (một phần trình duyệt web cụ thể):

  • Mật khẩu được truyền đi với mọi yêu cầu - ngay cả với SSL này có một số loại "linh cảm xấu" .
  • Vì mật khẩu được truyền đi với tiêu đề yêu cầu, sẽ dễ dàng cho kẻ tấn công địa phương xem xét các tiêu đề được truyền để nhận mật khẩu.
  • Mật khẩu có sẵn trong bộ nhớ trình duyệt.
  • Không có cách tiêu chuẩn để hết hạn "phiên" của người dùng.
  • Đăng nhập bằng trình duyệt sẽ làm gián đoạn giao diện của trang.

Những vấn đề đối với phương pháp thứ hai là tập trung hơn vào việc thực hiện và thư viện sử dụng:

  • Mỗi yêu cầu URI mà cần chứng thực phải có một tham số cho được dấu hiệu, mà chỉ là rất lặp đi lặp lại.
  • Có nhiều mã hơn để viết nếu mỗi phương thức triển khai cần kiểm tra xem mã thông báo có hợp lệ hay không.
  • Giao diện sẽ trở nên ít cụ thể hơn, ví dụ: [RestGet("/get/{id}")][RestGet("/get/{id}/{token}")].
  • Nơi đặt mã thông báo: ở cuối URI? sau gốc? ở đâu khác?

Ý tưởng của tôi là để vượt qua các dấu hiệu như tham số vào URL như http:/server/user/get/1234?token=token_id.

Một khả năng khác là gửi tham số dưới dạng tiêu đề HTTP, nhưng điều này sẽ làm phức tạp việc sử dụng với các máy khách HTTP thuần túy mà tôi đoán.

Mã thông báo sẽ được chuyển lại cho khách hàng dưới dạng tiêu đề HTTP tùy chỉnh ("X-Session-Id") trên mỗi yêu cầu.

Điều này sau đó có thể được tóm tắt hoàn toàn từ giao diện và mọi xác thực cần thực hiện chỉ có thể hỏi người dùng mã thông báo (nếu được) thuộc về.

Bạn có nghĩ điều này sẽ vi phạm REST quá nhiều hoặc bạn có ý tưởng nào tốt hơn không?

Trả lời

63

Tôi có xu hướng tin rằng chi tiết xác thực thuộc về tiêu đề, không phải là URI. Nếu bạn dựa vào mã thông báo được đặt trên URI, thì mọi URI trong ứng dụng của bạn sẽ cần phải được mã hóa để bao gồm mã thông báo. Nó cũng sẽ tác động tiêu cực đến bộ nhớ đệm. Tài nguyên có mã thông báo liên tục thay đổi sẽ không thể lưu vào bộ nhớ cache được nữa. Thông tin liên quan đến tài nguyên nằm trong URI, không phải dữ liệu liên quan đến ứng dụng như thông tin đăng nhập.

Dường như bạn phải nhắm mục tiêu các trình duyệt web với tư cách là khách hàng? Nếu vậy, bạn có thể điều tra bằng cách sử dụng HTTP Digest access authentication hoặc cấp cho khách hàng chứng chỉ SSL của riêng họ để xác định duy nhất và xác thực chúng. Ngoài ra, tôi không nghĩ rằng cookie phiên là nhất thiết phải là một điều xấu. Đặc biệt là khi phải đối phó với một trình duyệt. Miễn là bạn cô lập mã xử lý cookie và làm cho phần còn lại của ứng dụng không dựa vào nó, bạn sẽ ổn thôi. Điều quan trọng là chỉ lưu trữ danh tính của người dùng trong phiên, không có gì khác. Không lạm dụng trạng thái phiên phía máy chủ.

Nếu bạn đang nhắm mục tiêu khách hàng ngoài trình duyệt thì có một số phương pháp bạn có thể thực hiện. Tôi đã may mắn khi sử dụng cơ chế S3 Authentication của Amazon.

Tất cả điều này đều rất chủ quan. Độ tinh khiết và sau REST đối với lá thư đôi khi có thể không thực tế. Miễn là bạn giảm thiểu và cô lập hành vi đó, cốt lõi của ứng dụng của bạn vẫn có thể là RESTful. Tôi rất khuyên bạn nên RESTful Web Services làm nguồn thông tin và phương pháp REST tuyệt vời.

+2

Cảm ơn bạn đã liên kết S3. – Fionn

+0

Trong ví dụ S3, chúng chia sẻ khóa mã hóa với các máy khách - điều này là xấu, phải không? –

+0

Giống như bất kỳ loại mật mã bí mật được chia sẻ nào, điều quan trọng là cả hai bên duy trì bí mật của khóa. Về vấn đề đó, không còn tệ hơn là mật mã đối xứng. – laz

4

Xác thực còn lại tôi đã xem xử lý các phiên làm tài nguyên REST để tạo, hủy, v.v ... và sau đó ID phiên được chuyển đến và fro.Những cái tôi đã nhìn thấy có xu hướng sử dụng cookie phiên cho điều này vì đó là cách duy nhất để bảo đảm nó thực sự. Nếu bạn chuyển id phiên trong URL, bạn không có bất kỳ cách nào để thực sự xác thực nó đến từ đúng máy khách.

Xác thực là một vấn đề phức tạp với REST, vì nó yêu cầu một số trạng thái được giữ bên ngoài URL vi phạm nguyên tắc REST của URL là tất cả những gì được yêu cầu để thể hiện trạng thái.

+0

Vì nó sẽ allways sử dụng SSL nếu không được sử dụng nội bộ trong một mạng bảo mật và sử dụng UUID cho các phiên mà nó đến từ đâu không phải là một vấn đề. Và điều gì cản trở ai đó giả mạo cookie? – Fionn

+3

Tôi sẽ không nói rằng có URI là tất cả những gì được yêu cầu để đại diện cho nhà nước là một nguyên tắc của REST. Thay vào đó, có tài nguyên được địa chỉ và tất cả các trạng thái ứng dụng chứa trong yêu cầu có vẻ như là một cách tốt hơn để tuyên bố nó. – laz

+0

Bạn sẽ bảo mật cookie bằng MAC, ví dụ:các máy chủ có một bí mật và sẽ trao cho khách hàng các phiên mã thông báo sau: _ nơi mac được xây dựng như SHA1 ( _ ) Khi một khách hàng gửi một mã thông báo _ máy chủ phải kiểm tra xem _ bằng ordnungswidrig

16

Tôi đồng ý với workmad3, nếu thời gian cuộc sống của phiên cần được duy trì, bạn nên tạo tài nguyên phiên. Đăng trên tài nguyên đó bằng thông tin xác thực người dùng (xác thực cơ bản hoặc thông tin đăng nhập trong nội dung nội dung) sẽ trả về id phiên duy nhất. Xóa trên/session/{id} sẽ đăng xuất người dùng.

Nếu bạn muốn kiểm soát thời gian hết hạn phiên. Khi tạo phiên mới (đăng trên tài nguyên phiên), máy chủ sẽ đặt cookie trên phản hồi (sử dụng tiêu đề cookie thiết lập tiêu chuẩn). Cookie sẽ chứa thời gian hết hạn. Chuỗi cookie phải được mã hóa trên máy chủ, vì vậy chỉ máy chủ mới có thể mở cookie đó. Mọi yêu cầu hậu quả đối với máy chủ sẽ gửi cookie phiên trong tiêu đề cookie. (nó sẽ được thực hiện tự động cho bạn nếu khách hàng của bạn là một trình duyệt). Máy chủ cần phải "gia hạn" cookie cho mọi yêu cầu, tức là tạo cookie mới với thời gian hết hạn mới (mở rộng thời gian chờ của phiên). Hãy nhớ xóa cookie khi người dùng gọi xóa trên tài nguyên phiên.

Nếu bạn muốn ứng dụng của mình được bảo mật hơn, bạn có thể lưu trữ IP của khách hàng trong chính cookie, vì vậy khi một yêu cầu đến máy chủ có thể xác thực rằng nó được gửi từ máy khách "gốc". Nhưng hãy nhớ rằng giải pháp này có thể có vấn đề khi proxy có liên quan, bởi vì máy chủ có thể "nhìn thấy" tất cả các yêu cầu đến từ cùng một máy khách.

+0

Tôi không thấy sự cố với proxy ở đây. Nó chỉ là an ninh gia tăng được giảm bởi thực tế là một số khách hàng dường như giống nhau. Các cookie cũng phải là [httpOnly] (http://en.wikipedia.org/wiki/HTTP_cookie#HttpOnly_cookie). – maaartinus