2015-12-20 16 views
7

Giả sử chúng tôi có một số API RESTful có tài nguyên bị lộ mà chúng tôi muốn hiển thị. Người dùng cuối sẽ làm việc với API này thông qua các ứng dụng của khách hàng như ứng dụng dành cho thiết bị di động và ứng dụng khách Javascript chạy trên trình duyệt web.Cách xác minh tài nguyên nào mà mỗi người dùng có thể truy cập bằng OAuth và OpenID Connect?

Với OAuth 2.0, API RESTful này sẽ nằm trên Máy chủ tài nguyên và chúng tôi sẽ có một Máy chủ ủy quyền mà trên đó các ứng dụng khách được đăng ký. Sau đó, người dùng sẽ được đăng ký tại máy chủ ủy quyền và có thể cấp quyền cho các ứng dụng đó truy cập tài nguyên nhân danh họ hay không.

Vì vậy, khi người dùng truy cập một ứng dụng khách, anh ta sẽ được chuyển hướng đến Máy chủ ủy quyền và được nhắc cấp quyền cho ứng dụng khách được cho biết. Sau đó một mã thông báo truy cập được phát hành và máy khách có thể thực hiện các yêu cầu tới Máy chủ tài nguyên.

Tất cả điều này khá rõ ràng đối với tôi. Chỉ có một phần còn thiếu: việc bảo vệ mỗi tài nguyên có thể phụ thuộc vào người dùng. Để chính xác hơn, có thể phụ thuộc vào xác nhận quyền sở hữu. Những gì tôi có ý nghĩa bởi đó là chúng ta có thể có các tình huống sau đây:

Khi tôi lần đầu tiên nghe nói về OAuth được giao dịch với ASP.NET WebAPI và tôi xử lý với điều đó theo cách sau: khi yêu cầu được gửi với Authorization: Bearer [token] tiêu đề, trên phía máy chủ hiệu trưởng chủ đề đã được thiết lập và tôi nghĩ rằng điều này có nghĩa là người dùng đã được xác thực với API. Vì vậy, tôi đã sử dụng các thuộc tính [Authorize] để xác minh xem người dùng có thể truy cập tài nguyên hay không.

Sau khi nghiên cứu sâu hơn về OAuth, tôi thấy đây là một sự lạm dụng sai của giao thức. Như tôi đã biết, OAuth cho phép ứng dụng chứ không phải người dùng. Khi yêu cầu được thực hiện với tiêu đề Cấp quyền, như tôi đã học, mã thông báo truy cập không được chứa thông tin về người dùng, chỉ về ứng dụng được phép thực hiện yêu cầu.

Xem xét việc gửi tiêu đề Cấp quyền với yêu cầu không xác định người dùng và không nói liệu người dùng có thể hoặc không thể truy cập tài nguyên được cho biết.

Trong trường hợp đó, cách thức thực hiện loại ủy quyền này? Ý tôi là, không cho phép ứng dụng khách thực hiện yêu cầu, nhưng ủy quyền của người dùng truy cập tài nguyên dựa trên các xác nhận quyền sở hữu của anh ta? Tôi tin rằng đây là nơi OpenID Connect và mã ID của nó xuất hiện, nhưng tôi không chắc chắn. Làm thế nào để quản lý điều này?

Trả lời

8

Mã thông báo truy cập không chứa xác nhận quyền sở hữu của người dùng, nhưng nó chứa chủ đề của người dùng đã cấp quyền cho ứng dụng khách. "Chủ đề" là thuật ngữ kỹ thuật và có nghĩa là một số nhận dạng duy nhất. Nói một cách đơn giản, "subject" là một ID người dùng trong cơ sở dữ liệu của bạn.

Tại một thiết bị đầu cuối nguồn được bảo vệ, bạn sẽ làm gì:

  1. Trích xuất một thẻ truy cập từ yêu cầu.(RFC 6750)
  2. Nhận thông tin chi tiết về mã thông báo truy cập từ máy chủ ủy quyền. (RFC 7662)
  3. Xác thực mã thông báo truy cập. Việc xác thực bao gồm (a) liệu mã thông báo truy cập đã hết hạn hay chưa và (b) liệu mã thông báo truy cập có bao gồm phạm vi (quyền) được yêu cầu bởi điểm cuối tài nguyên được bảo vệ hay không.

Các bước trên từ 1 đến 3 là kiểm soát truy cập đối với ứng dụng khách. OAuth 2.0 (RFC 6749) là dành cho việc này. Xem "Protected Resource" theo số Authlete (của tôi) để biết chi tiết về các bước này.

Sau các bước trên, sau đó bạn sẽ làm gì:

  1. Extract Đối tượng từ thẻ truy cập. Một lần nữa, "chủ đề" là một định danh duy nhất của người dùng.
  2. Truy xuất xác nhận quyền sở hữu của người dùng từ cơ sở dữ liệu của bạn.
  3. Xác thực các xác nhận quyền sở hữu theo ý muốn của bạn.

Các bước trên từ 4 đến 6 là kiểm soát truy cập đối với người dùng. OAuth 2.0 KHÔNG dành cho điều này.

Mục đích chính của OpenID Connect là lấy ID token một cách có thể kiểm chứng. Bạn có thể xác nhận rằng mã thông báo ID đã được cấp bởi bên phải bằng cách xác minh chữ ký được gắn với mã thông báo ID. Xem Chữ ký Web JSON (JWS) (RFC 7515) để biết chi tiết về chữ ký.

Bản thân mã thông báo ID không phải là công nghệ bảo vệ các API Web. Nhưng bạn có thể sử dụng nó cho mục đích đó nếu bạn sử dụng yêu cầu at_hash trong mã thông báo ID đúng cách (xem "3.1.3.6. ID Token" trong OpenID Connect Core 1.0). Tuy nhiên, tại điểm cuối tài nguyên được bảo vệ, sẽ dễ dàng hơn nhiều để nhận được xác nhận quyền sở hữu trực tiếp từ cơ sở dữ liệu của bạn hơn là phân tích mã thông báo ID.


[câu trả lời bổ sung # 1 cho các lời bình]

Trong trường hợp sử dụng của bạn, bạn không cần thẻ ID. Đó là do mã thông báo truy cập đã chứa thông tin về chủ đề của người dùng. Trong các trường hợp thông thường, thông tin tương đương với giá trị của yêu cầu sub trong mã thông báo ID.

enter image description here

Vì vậy, bạn không cần một thẻ ID để có được những đối tượng người dùng. Xem mô tả của bước 4 và bạn có thể tìm thấy "trích xuất chủ đề từ mã thông báo truy cập ".


[bổ sung câu trả lời # 2 cho lời bình]

Vậy là có bất cứ điều gì sai trong chiết xuất chủ đề từ các thẻ truy cập như thế và xác minh những tuyên bố? Hay đây là cách làm đúng đắn?

Không có gì sai. Ví dụ: giả sử bạn xác định API Web, https://api.example.com/profile, trả về thông tin tiểu sử của người dùng. Trong các trường hợp bình thường, một API như vậy sẽ chấp nhận mã thông báo truy cập và sau đó trích xuất chủ đề từ mã thông báo truy cập để xác định người dùng nào cần tham chiếu. Mặt khác, nếu API không trích xuất chủ đề từ mã thông báo truy cập, API sẽ phải yêu cầu "subject" làm tham số yêu cầu để xác định người dùng nào cần tham chiếu đến (hoặc yêu cầu mã thông báo ID chứa xác nhận quyền sở hữu "phụ") . Ngay cả trong trường hợp như vậy, API phải kiểm tra xem đối tượng được chỉ định bởi tham số yêu cầu và chủ đề được liên kết với mã thông báo truy cập có giống nhau hay không vì nếu không nó sẽ trở thành vấn đề bảo mật.

Kiểm tra xác nhận quyền sở hữu sau khi trích xuất đối tượng cũng là một bước bình thường. Ví dụ: bạn có thể muốn hạn chế các chức năng của dịch vụ dựa trên kế hoạch mà người dùng đã thanh toán (Kế hoạch miễn phí, gói Lite, gói Enterprise hoặc bất kỳ thứ gì). Trong trường hợp này, bạn sẽ phải tham khảo yêu cầu plan. Tất nhiên, việc kiểm tra một yêu cầu như vậy chỉ có thể được thực hiện sau khi trích xuất chủ đề từ mã thông báo truy cập.

Do đó, (1) trích xuất chủ đề từ mã thông báo truy cập và sau đó (2) xác minh xác nhận quyền sở hữu của người dùng là bình thường và thậm chí là các bước điển hình trong việc triển khai các điểm cuối tài nguyên được bảo vệ.

+0

Cảm ơn sự giúp đỡ một lần nữa @TakahikoKawasaki. Tôi nghĩ rằng tôi nhận được nó ngay bây giờ. Cuối cùng, chúng tôi sử dụng mã thông báo truy cập OAuth để có quyền kiểm soát truy cập đối với các ứng dụng của khách hàng: khách hàng nào có thể truy cập tài nguyên nào. Sau đó, từ mã thông báo nhận dạng OpenID Connect, chúng tôi có quyền kiểm soát truy cập đối với người dùng: chúng tôi chọn xác nhận quyền sở hữu chủ đề từ mã thông báo ID xác định người dùng và xem cơ sở dữ liệu nếu người dùng có yêu cầu quyền truy cập tài nguyên. Cuối cùng, thay vì di chuyển xác nhận quyền sở hữu, chúng tôi di chuyển đối tượng bên trong mã thông báo nhận dạng và xác minh các yêu cầu cần thiết khi ủy quyền. Là nó? – user1620696

+0

Đã chỉnh sửa câu trả lời cho nhận xét của bạn. –

+0

Cảm ơn câu trả lời chi tiết @TakahikoKawasaki. Chỉ một điểm, bạn đã nói ở bước 4 "OAuth 2.0 KHÔNG dành cho điều này" và tôi hiểu điều này, vì mục tiêu của OAuth là kiểm soát truy cập đối với các ứng dụng của khách hàng. Vì vậy, có điều gì sai trong việc trích xuất chủ đề từ mã thông báo truy cập như vậy và xác minh các xác nhận quyền sở hữu không? Hay đây là cách làm đúng đắn? Xin lỗi vì rất nhiều nghi ngờ, tôi thực sự không có chuyên gia về bảo mật và tôi chỉ mới bắt đầu với OAuth và OpenID Connect. – user1620696

1

Bạn nói đúng, OAuth là NOT an authentication protocol nhưng đúng hơn là giao thức ủy quyền.

Kết nối OpenID thêm hai cấu trúc nhận dạng đáng chú ý vào mô hình phát hành mã thông báo OAuth 2.0.

  • một Identity Token - việc cung cấp trong đó từ một bên để khác có thể kích hoạt một kinh nghiệm người dùng định liên đoàn SSO API thuộc tính

  • một bản sắc chuẩn - mà tại đó một khách hàng có thể
    lấy mong muốn bản sắc các thuộc tính cho một người dùng cụ thể.

Mã thông báo ID có thể được trình bày cho userinfo_endpoint để nhận thông tin và cung cấp mức độ bảo đảm mà người dùng đã được xác thực bởi nhà cung cấp OpenID.

BTW: Ví dụ "phụ" chỉ duy nhất trong ngữ cảnh của Máy chủ ủy quyền. Đó là khuyến cáo NẾU bạn lưu trữ phụ bạn cũng lưu trữ một cái gì đó như iss-sub. Những suy nghĩ là tsmith tại Google có thể không được tsmith tại Twitter

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