Sự khác biệt giữa Mã ủy quyền OAuth và quy trình công việc tiềm ẩn là gì? Khi nào nên sử dụng mỗi một?


165

OAuth 2.0 có nhiều quy trình công việc. Tôi có một vài câu hỏi liên quan đến hai.

  1. Luồng mã ủy quyền - Người dùng đăng nhập từ ứng dụng khách, máy chủ ủy quyền trả lại mã ủy quyền cho ứng dụng. Sau đó, ứng dụng trao đổi mã ủy quyền để truy cập mã thông báo.
  2. Luồng cấp quyền ngầm định - Người dùng đăng nhập từ ứng dụng khách, máy chủ ủy quyền cấp mã thông báo truy cập trực tiếp vào ứng dụng khách.

Sự khác biệt giữa hai phương pháp bảo mật là gì? Cái nào an toàn hơn và tại sao?

Tôi không thấy lý do tại sao một bước bổ sung (mã ủy quyền trao đổi mã thông báo) được thêm vào trong một luồng công việc khi máy chủ có thể trực tiếp phát hành Mã thông báo truy cập.

Các trang web khác nhau nói rằng luồng mã ủy quyền được sử dụng khi ứng dụng khách có thể giữ thông tin đăng nhập an toàn. Tại sao?


Câu trả lời:


204

Đây access_tokenlà những gì bạn cần để gọi một tài nguyên được bảo vệ (API). Trong luồng Mã ủy quyền có 2 bước để có được nó:

  1. Người dùng phải xác thực và trả lại codecho người tiêu dùng API (được gọi là "Máy khách").
  2. "Máy khách" của API (thường là máy chủ web của bạn) trao đổi số 1 codethu được cho một access_token, xác thực chính nó bằng một client_idclient_secret
  3. Sau đó, nó có thể gọi API với access_token.

Vì vậy, có một kiểm tra kép: người dùng sở hữu tài nguyên nổi lên thông qua API và ứng dụng khách sử dụng API (ví dụ: ứng dụng web). Cả hai đều được xác nhận để truy cập được cấp. Lưu ý bản chất "ủy quyền" của OAuth tại đây: người dùng cấp quyền truy cập vào tài nguyên của anh ta (thông qua codetrả lại sau khi xác thực) cho một ứng dụng, ứng dụng nhận được access_tokenvà gọi nhân danh người dùng.

Trong luồng ngầm, bước 2 được bỏ qua. Vì vậy, sau khi xác thực người dùng, một access_tokentrả lại trực tiếp, mà bạn có thể sử dụng để truy cập tài nguyên. API không biết ai đang gọi API đó. Bất cứ ai có access_tokenthể, trong khi trong ví dụ trước chỉ có ứng dụng web sẽ làm (đó là nội bộ thường không thể truy cập được cho bất kỳ ai).

Luồng ngầm thường được sử dụng trong các tình huống lưu trữ client idclient secretkhông được khuyến nghị (ví dụ như một thiết bị, mặc dù nhiều người vẫn làm như vậy). Đó là những gì từ chối trách nhiệm. Mọi người có quyền truy cập vào mã máy khách và do đó có thể có được thông tin đăng nhập và giả vờ trở thành khách hàng tài nguyên. Trong luồng ngầm, tất cả dữ liệu đều biến động và không có gì được lưu trữ trong ứng dụng.


Cảm ơn lời giải thích của bạn nhưng tôi không hiểu tại sao chúng ta cần một luồng Mã ủy quyền khác. Chúng tôi có thể đạt được kết quả tương tự trên máy chủ bằng luồng ngầm định (access_token) và mã thông báo làm mới. Có vẻ như sự cân nhắc bảo mật duy nhất của luồng ngầm là access_code nên có tuổi thọ ngắn để không thể sử dụng nó trên máy chủ đến máy chủ. OK, nhưng mã thông báo làm mới giải quyết vấn đề này. Tại sao chúng ta nên sử dụng luồng auth_code và yêu cầu access_token trên máy chủ để lấy access_code?
Mohammad Nikravan

Chà ... đó là cách giao thức hoạt động. Bạn có thể muốn đọc phân tích mối đe dọa cụ thể để tham khảo chi tiết hơn về giá trị bảo mật của cái này và cái kia.
Eugenio Pace

Tôi biết câu trả lời ban đầu là hơn 5 năm, nhưng đây là lời giải thích đơn giản và gọn gàng nhất tôi từng đọc. Cảm ơn bạn @EugenioPace
Taha Ahmad

1
@ Madnik7G Lý do là trực giao với những gì câu trả lời này giải thích (rất hay): có thể có bên thứ ba tham gia. Toàn bộ luồng được phối hợp bởi một tác nhân người dùng (ví dụ: trình duyệt), nhưng cuối cùng, máy chủ ủy quyền (ví dụ: "Đăng nhập bằng Facebook") sẽ nói chuyện trực tiếp với khách hàng (giả sử, BFF phía máy chủ của bạn) sẽ cuối cùng truy cập tài nguyên, để tác nhân người dùng không bao giờ có quyền truy cập trực tiếp.
Daniel Langdon

Cảm ơn! Có, có 3 giao tiếp đang diễn ra: trình duyệt và AS 9e.g. Facebook). Đó là /authorizeyêu cầu. Trình duyệt và trang web cố gắng gọi API (còn gọi là máy khách). Đó là redirect_uri+ được codetrả về bởi AS sau khi xác thực thành công. Cuối cùng, khách hàng gọi AS đằng sau hậu trường, đổi codelấy một access_token. Đây là token endpointtrong các tài liệu. Nói chung, AS không bao giờ gọi bất cứ ai. Nó luôn trả lời.
Eugenio Pace

52

Tôi sẽ thêm một cái gì đó ở đây mà tôi không nghĩ được làm rõ trong các câu trả lời ở trên:

  • Luồng ủy quyền-Mã cho phép mã thông báo truy cập cuối cùng không bao giờ tiếp cận và không bao giờ được lưu trữ trên máy bằng trình duyệt / ứng dụng . Mã ủy quyền tạm thời được trao cho máy có trình duyệt / ứng dụng, sau đó được gửi đến máy chủ. Sau đó, máy chủ có thể trao đổi nó với mã thông báo truy cập đầy đủ và có quyền truy cập vào API, v.v. Người dùng có trình duyệt chỉ được truy cập vào API thông qua máy chủ có mã thông báo.
  • Luồng ngầm định chỉ có thể có sự tham gia của hai bên và mã thông báo truy cập cuối cùng được lưu trữ trên máy khách với trình duyệt / ứng dụng. Nếu trình duyệt / ứng dụng này bị xâm phạm thì mã xác thực của họ có thể gây nguy hiểm.

tl; dr không sử dụng dòng chảy ngầm nếu bạn không tin tưởng vào máy người dùng thẻ giữ nhưng bạn làm tin tưởng các máy chủ của riêng bạn.


12
re: Người dùng có trình duyệt chỉ được truy cập API thông qua máy chủ có mã thông báo. Nhưng máy chủ cần gửi một cái gì đó đến trình duyệt để các yêu cầu gửi đến có thể được liên kết với mã thông báo được giữ ở phía máy chủ. Một cookie nếu bạn thích. Nếu máy chủ không truyền mã thông báo đến JS đang chạy trong trình duyệt, thì nó phải truyền một thứ khác, mà máy khách (trình duyệt) cần truyền đến máy chủ, để cho phép máy chủ hành động thay mặt cho máy khách cụ thể.
Cheeso

Vâng, một cái bánh quy. Vì vậy, bạn nên thiết lập máy chủ và ứng dụng khách trình duyệt của mình để được bảo vệ chống lại giả mạo yêu cầu trên nhiều trang web.
Marcel

@Marcel Tôi muốn biết rằng một khi chúng tôi nhận được mã, cách thức và nơi trao đổi xảy ra để có được thực tế access_tokenvới sự giúp đỡ của authorization code.
chirag soni

14

Sự khác biệt giữa cả hai là:

  1. Trong luồng ngầm định, mã thông báo được trả lại trực tiếp qua URL chuyển hướng có dấu "#" và điều này được sử dụng chủ yếu trong các ứng dụng khách javascript hoặc ứng dụng di động không có phía máy chủ và khách hàng không cần cung cấp bí mật trong một số triển khai .

  2. Trong luồng mã ủy quyền, mã được trả về bằng "?" để có thể đọc được bởi phía máy chủ thì phía máy chủ phải cung cấp bí mật cho khách hàng lần này để mã thông báo url để nhận mã thông báo dưới dạng đối tượng json từ máy chủ ủy quyền. Nó được sử dụng trong trường hợp bạn có máy chủ ứng dụng có thể xử lý việc này và lưu trữ mã thông báo người dùng với hồ sơ của anh ấy / cô ấy trên hệ thống của mình và chủ yếu được sử dụng cho các ứng dụng di động phổ biến.

do đó, tùy thuộc vào bản chất của ứng dụng khách của bạn, một "Mã ủy quyền" an toàn hơn vì nó yêu cầu bí mật về máy khách và mã thông báo có thể được gửi giữa máy chủ ủy quyền và ứng dụng khách trên kết nối rất an toàn và nhà cung cấp ủy quyền có thể hạn chế một số khách hàng chỉ sử dụng "Mã ủy quyền" và không cho phép Ẩn


Mã ủy quyền được lưu trữ ở phía máy chủ trong 10 phút cho facebook. Điều này đã được phát hành trong thay đổi tháng 5 năm 2012 của họ. Câu hỏi của tôi chủ yếu là, sự khác biệt giữa 2 về bảo mật / hiệu suất. Tôi biết cả hai luồng làm gì - nhưng lợi thế của việc sử dụng mã ủy quyền là gì - thêm một bước nữa vào quy trình làm việc.
divyanshm

Nó không gửi mã thông báo đến ứng dụng người dùng, kết nối giữa ứng dụng khách và máy chủ ủy quyền bị ẩn khỏi người dùng và như tôi đã đề cập, đây có thể là kênh rất an toàn không giống với kênh từ người dùng đến ứng dụng khách.
Bassem Reda Zohdy

hiệu suất trong mã ủy quyền bạn đã nhấn máy chủ xác thực hai lần để mất nhiều thời gian hơn, máy chủ khách sẽ lưu trữ mã thông báo người dùng và điều này cũng sẽ thêm nhiều thời gian hơn.
Bassem Reda Zohdy

2
Ồ được rồi! Tôi có thể đã bỏ qua điều này. Về cơ bản, luồng mã ủy quyền sẽ được sử dụng bởi các hệ thống trong đó toàn bộ máy chủ là máy khách - trình duyệt thực hiện yêu cầu và nhận mã. mã được gửi đến máy chủ khách kết nối với máy chủ tài nguyên một cách an toàn. Tôi có hiểu đúng không? Mã thông báo truy cập không bao giờ đến được máy của người dùng cuối?
divyanshm

1
Mã thông báo truy cập không bao giờ đến được máy của người dùng cuối? có, nó được liên kết với hồ sơ của bạn với máy chủ ứng dụng khách.
Bassem Reda Zohdy

4

Cấp quyền ngầm tương tự như cấp mã ủy quyền với hai điểm khác biệt rõ ràng.

Nó được dự định sẽ được sử dụng cho các máy khách dựa trên tác nhân người dùng (ví dụ: ứng dụng web một trang) không thể giữ bí mật ứng dụng khách vì tất cả các mã ứng dụng và lưu trữ đều có thể truy cập dễ dàng.

Thứ hai, thay vì máy chủ ủy quyền trả lại mã ủy quyền được trao đổi cho mã thông báo truy cập, máy chủ ủy quyền sẽ trả lại mã thông báo truy cập.

Vui lòng tìm chi tiết tại đây http://oauth2.thephpleague.com/authorization-server/which-grant/


1
Cảm ơn liên kết đó, nó đã giúp tôi hiểu sự khác biệt giữa từng loại cấp và khi chọn từng loại.
François POYER

3

Dòng chảy ngầm

Ưu điểm

  • Đơn giản nhất để thực hiện

Nhược điểm

  • Mã thông báo truy cập hiển thị cho trình duyệt
  • Nguồn gốc của mã thông báo truy cập không thể được xác định
  • Mã thông báo truy cập không thể hết hạn (theo chính sách của Google)

Luồng mã ủy quyền

Ưu điểm

  • An toàn nhất
  • Mã thông báo truy cập và mã thông báo làm mới chỉ có thể được tạo nếu biết một bí mật chung
  • Có thể được tăng cường với các tính năng bảo mật và UX mới khi chúng có sẵn

Nhược điểm

  • Phải thực hiện nhiều điểm cuối auth

Trích dẫn: https://developers.google.com/ilities/develop/identity/oauth2-overview#supported_oauth_20_flows


2

Hãy để tôi tóm tắt những điểm mà tôi học được từ các câu trả lời ở trên và thêm một số hiểu biết của riêng tôi.

Lưu lượng ủy quyền !!!

  • Nếu bạn có một máy chủ ứng dụng web hoạt động như máy khách OAuth
  • Nếu bạn muốn có quyền truy cập lâu dài
  • Nếu bạn muốn có quyền truy cập ngoại tuyến vào dữ liệu
  • khi bạn chịu trách nhiệm cho các cuộc gọi api mà ứng dụng của bạn thực hiện
  • Nếu bạn không muốn rò rỉ mã thông báo OAuth của mình
  • Nếu bạn không muốn ứng dụng của bạn chạy qua luồng ủy quyền mỗi khi ứng dụng cần truy cập vào dữ liệu. LƯU Ý: Luồng cấp phát ngầm không giải trí mã thông báo làm mới vì vậy nếu máy chủ ủy quyền hết hạn mã thông báo truy cập, ứng dụng của bạn sẽ cần chạy qua luồng ủy quyền bất cứ khi nào cần truy cập.

Dòng chảy ngầm tiềm ẩn !!!

  • Khi bạn không có Máy chủ ứng dụng web để hoạt động như Máy khách OAuth
  • Nếu bạn không cần truy cập lâu dài, tức là chỉ cần truy cập tạm thời vào dữ liệu.
  • Nếu bạn tin tưởng vào trình duyệt nơi ứng dụng của bạn chạy và có mối lo ngại hạn chế rằng mã thông báo truy cập sẽ bị rò rỉ cho người dùng không tin cậy.

2

Cái nào an toàn hơn và tại sao?

Cả hai đều an toàn, nó phụ thuộc vào môi trường bạn đang sử dụng nó.

Tôi không thấy lý do tại sao một bước bổ sung (mã ủy quyền trao đổi mã thông báo) được thêm vào trong một luồng công việc khi máy chủ có thể trực tiếp phát hành Mã thông báo truy cập.

Nó đơn giản. Khách hàng của bạn không an toàn. Chúng ta hãy xem chi tiết.

Hãy xem xét bạn đang phát triển một ứng dụng Instagram API, vì vậy bạn đăng ký APP Instagramvà xác định những API'sgì bạn cần. Instagramsẽ cung cấp cho bạn client_idclient_secrect

Trên trang web của bạn, bạn thiết lập một liên kết mà nói. "Hãy đến và sử dụng ứng dụng của tôi". Nhấp vào ứng dụng web này của bạn sẽ thực hiện hai cuộc gọi đến Instagram API.

Firstgửi yêu cầu Instagram Authentication Servervới các tham số dưới đây.

1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token. 

Bạn không gửiclient_secret , Bạn không thể tin tưởng khách hàng (Người dùng và trình duyệt của anh ta đang cố sử dụng ứng dụng của bạn). Máy khách có thể xem tập lệnh url hoặc java và tìm thấy bạn client_secrectdễ dàng. Đây là lý do tại sao bạn cần một bước khác.

Bạn nhận được một codestate. Đây codetemporaryvà không được lưu bất kỳ nơi nào.

Sau đó, bạn thực hiện secondcuộc gọi đến Instagram API(từ máy chủ của bạn)

 1. `grant_type` with the value of `authorization_code`
 2. `client_id` with the client identifier
 3. `client_secret` with the client secret
 4. `redirect_uri` with the same redirect URI the user was redirect back to
 5. `code` which we have already received.

Vì cuộc gọi được thực hiện từ máy chủ của chúng tôi, chúng tôi có thể sử dụng một cách an toàn client_secret(cho thấy chúng tôi như thế nào) với codeđiều đó cho thấy người dùng đã được cấp quyền client_idsử dụng tài nguyên.

Đáp lại chúng ta sẽ có access_token


1

Từ quan điểm thực tế (Những gì tôi hiểu), lý do chính để có dòng mã Authz là:

  1. Hỗ trợ làm mới mã thông báo (truy cập dài hạn bởi các ứng dụng thay mặt cho Người dùng), không được hỗ trợ trong ẩn: tham khảo: https://tools.ietf.org/html/rfc6749#section-4.2
  2. Hỗ trợ cho trang đồng ý là nơi mà Chủ sở hữu tài nguyên có thể kiểm soát quyền truy cập để cung cấp (Loại quyền / trang ủy quyền mà bạn thấy trong google). Tương tự là không có trong ngầm. Xem phần: https://tools.ietf.org/html/rfc6749#section-4.1 , điểm (B)

"Máy chủ ủy quyền xác thực chủ sở hữu tài nguyên (thông qua tác nhân người dùng) và thiết lập xem chủ sở hữu tài nguyên có cấp hoặc từ chối yêu cầu truy cập của khách hàng hay không"

Ngoài ra, Sử dụng mã thông báo làm mới, Ứng dụng có thể truy cập lâu dài vào dữ liệu người dùng.


0

Dường như có hai điểm chính, chưa được thảo luận cho đến nay, điều này giải thích tại sao đường vòng trong Loại Cấp phép Mã ủy quyền bổ sung bảo mật.

Câu chuyện ngắn : Loại Cấp phép Mã ủy quyền lưu giữ thông tin nhạy cảm từ lịch sử trình duyệt và việc truyền mã thông báo chỉ phụ thuộc vào bảo vệ HTTPS của máy chủ ủy quyền.

Phiên bản dài hơn:

Sau đây, tôi sẽ sử dụng thuật ngữ OAuth 2 được xác định trong RFC (đó là cách đọc nhanh): máy chủ tài nguyên , máy khách , máy chủ ủy quyền , chủ sở hữu tài nguyên .

Hãy tưởng tượng bạn muốn một số ứng dụng của bên thứ ba (= khách hàng) truy cập vào một số dữ liệu nhất định của tài khoản Google của bạn (= máy chủ tài nguyên). Giả sử Google sử dụng OAuth 2. Bạn là chủ sở hữu tài nguyên cho tài khoản Google, nhưng ngay bây giờ bạn vận hành ứng dụng của bên thứ ba.

Đầu tiên, khách hàng mở trình duyệt để gửi bạn đến URL an toàn của máy chủ ủy quyền của Google. Sau đó, bạn chấp thuận yêu cầu truy cập và máy chủ ủy quyền sẽ gửi lại cho bạn URL chuyển hướng được cung cấp trước đó của khách hàng, với mã ủy quyền trong chuỗi truy vấn. Bây giờ cho hai điểm chính:

  1. URL của chuyển hướng này kết thúc trong lịch sử trình duyệt . Vì vậy, chúng tôi không muốn mã thông báo truy cập trực tiếp có thể sử dụng lâu dài ở đây. Mã ủy quyền tồn tại trong thời gian ngắn ít nguy hiểm hơn trong lịch sử. Lưu ý rằng loại Grant tiềm ẩn sẽ đưa mã thông báo vào lịch sử.
  2. Tính bảo mật của chuyển hướng này phụ thuộc vào chứng chỉ HTTPS của khách hàng , không phụ thuộc vào chứng chỉ của Google. Vì vậy, chúng tôi nhận bảo mật truyền của máy khách như một vectơ tấn công bổ sung (Để điều này là không thể tránh khỏi, máy khách cần phải không phải là JavaScript. Vì nếu không, chúng tôi có thể truyền mã ủy quyền qua URL phân đoạn, nơi mã sẽ không đi qua mạng. Đây có thể là lý do tại sao Implicit Grant Type, mà không sử dụng một URL mảnh, sử dụng được khuyến cáo cho khách hàng JavaScript, mặc dù đó là không còn như vậy.)

Với Loại Cấp phép Mã ủy quyền, mã thông báo cuối cùng nhận được bằng một cuộc gọi từ máy khách đến máy chủ ủy quyền, trong đó bảo mật truyền chỉ phụ thuộc vào máy chủ ủy quyền , không phụ thuộc vào máy khách.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.