Mục đích của thời gian hết hạn Mã thông báo ID trong OpenID Connect là gì?


92

Trong OpenID Connect, mã thông báo truy cập có thời hạn sử dụng. Đối với luồng mã ủy quyền, thời gian này thường ngắn (ví dụ: 20 phút), sau đó bạn sử dụng mã làm mới để yêu cầu mã thông báo truy cập mới.

Các ID Mã thông báo cũng có một thời gian hết hạn. Câu hỏi của tôi là mục đích của việc này là gì?

Bất kỳ thời gian hết hạn nào của mã thông báo ID nhỏ hơn thời gian hết hạn của mã thông báo làm mới sẽ có nghĩa là cuối cùng bạn sẽ có mã thông báo ID đã hết hạn, nhưng là mã thông báo truy cập hợp lệ.

Vì vậy, bạn có ý định:

  • cung cấp cho mã thông báo ID của bạn hết hạn lâu hơn thời hạn sử dụng mã thông báo làm mới hoặc
  • đặt nó thành thời hạn sử dụng giống như mã thông báo truy cập và thực hiện một số hành động (cái gì?) khi nó hết hạn, hoặc
  • chỉ sử dụng mã thông báo ID trong khách hàng của bạn khi nhận, sau đó bỏ qua thời gian hết hạn sau đó?

Thông số kỹ thuật của OpenID Connect chỉ nói rằng khi xác thực mã thông báo ID,

"The current time MUST be before the time represented by the exp Claim."

mà (có thể) hỗ trợ tùy chọn thứ ba ở trên.


BIÊN TẬP

Khi OpenID Connect xây dựng trên OAuth2, bạn có thể tìm thấy câu trả lời cho câu hỏi bổ sung bên dưới trong thông số kỹ thuật OAuth2 cho biết,

expires_in
     RECOMMENDED.  The lifetime in seconds of the access token.

Một câu hỏi liên quan là khi bạn trao đổi mã ủy quyền cho các mã thông báo, thông số kỹ thuật tương tự cho biết bạn có thể nhận được phản hồi như:

{
 "access_token": "SlAV32hkKG",
 "token_type": "Bearer",
 "refresh_token": "8xLOxBtZp8",
 "expires_in": 3600,
 "id_token": "eyJhbG[...]"
}

Nhưng "expires_in" liên quan gì trong trường hợp này? Mã thông báo truy cập, mã làm mới hoặc mã thông báo ID?

(Để biết thông tin, IdentityServer3 đặt điều này thành thời gian hết hạn mã thông báo truy cập).

Câu trả lời:


90

Tôi đang trả lời câu hỏi của chính mình vì đã phát hiện ra rằng một số giả định đằng sau câu hỏi của tôi là sai, vì vậy sẽ dễ dàng làm rõ hơn ở đây, thay vì viết lại câu hỏi.

Mã thông báo ID có nghĩa là để chứng minh cho Khách hàng rằng người dùng đã xác thực và kết quả là họ là ai.

Khi Khách hàng nhận được mã thông báo ID, nó thường sẽ thực hiện một số việc như chuyển đổi nó thành ClaimsIdentity và duy trì điều này, ví dụ: sử dụng cookie.

Mã thông báo ID phải chưa hết hạn tại thời điểm sử dụng này (nên có, vì nó mới được phát hành). Nhưng sau đó nó không được sử dụng nữa, vì vậy nó không thành vấn đề nếu nó hết hạn trong khi người dùng vẫn còn một phiên hoạt động. Khách hàng có thông tin xác thực cần thiết và đến lượt nó, có thể chọn chính sách của riêng mình trong thời gian phiên kéo dài bao lâu trước khi người dùng phải đăng nhập lại.

Giả định sai lầm của tôi khi đặt câu hỏi là mã thông báo ID và mã thông báo truy cập phải được sử dụng cùng nhau và do đó cả hai đều cần phải có ngày hết hạn hợp lệ. Điều này sai vì nhiều lý do:

  • Mã thông báo ID chỉ để xác thực cho Khách hàng (như mô tả ở trên).
  • Mã thông báo truy cập không liên quan gì đến Khách hàng. Chúng dành cho quyền truy cập vào các tài nguyên và Máy khách chỉ xử lý chúng nếu đến lượt nó cần gọi một tài nguyên.
  • Một cái gì đó giống như ứng dụng MVC hoặc WebForms độc lập chỉ cần mã thông báo ID. Nếu nó không gọi một tài nguyên bên ngoài, thì không có gì để cấp quyền truy cập, vì vậy không có mã thông báo truy cập.

3
Bạn có bất kỳ tài liệu tham khảo cho điều này? Eugenio tuyên bố bạn có thể làm mới mã thông báo id trong câu trả lời của anh ấy. Điều này có đúng không?
AndyD

6
Bạn không thể làm mới mã thông báo ID, theo nghĩa là kéo dài thời hạn của nó (theo cách một mã thông báo truy cập có thể được làm mới bằng cách sử dụng mã thông báo truy cập ngoại tuyến). Nhưng nếu bạn có một phiên xác thực chưa hết hạn với Nhà cung cấp kết nối OpenID (ví dụ: một cookie sau khi đăng nhập vào IdentityServer3) thì khi bạn lặp lại yêu cầu đăng nhập, Nhà cung cấp có thể bỏ qua xác thực (vì cookie cho biết bạn đã làm điều đó) và chỉ trả về Mã thông báo ID mới (& mã thông báo truy cập nếu được yêu cầu). Tất nhiên, điều này chỉ hoạt động nếu cookie có thời gian tồn tại lâu hơn ID Token.
Appetere

1
Mặc dù bạn có thể làm điều này, nhưng tôi không chắc liệu làm như vậy có đúng không. Nó cũng sẽ không liền mạch với người dùng cuối, vì nó sẽ yêu cầu một số ít chuyển hướng trình duyệt.
Kir

@Kir Nếu bạn đang sử dụng ứng dụng một trang Javascript (SPA) thì nỗ lực đầu tiên để gia hạn mã thông báo tài khoản thường là một quy trình nền, vì vậy người dùng cuối sẽ không bị gián đoạn. Ví dụ: nếu API tài nguyên của bạn phản hồi rằng mã thông báo truy cập đã hết hạn, thì SPA sẽ đưa ra yêu cầu nền tới Máy chủ nhận dạng để có mã thông báo truy cập mới. Chỉ khi điều này không thành công (vì mã thông báo ID đã hết hạn) thì bạn mới phải yêu cầu người dùng đăng nhập lại. Xem ví dụ về mẫu JavascriptImplicitClient tại github.com/IdentityServer/IdentityServer3.Samples/tree/master/… .
Appetere

Bạn có thể làm mới Id_token, nếu nhà cung cấp OIdC hỗ trợ trả lại nó từ yêu cầu Refresh_token. Xem stackoverflow.com/questions/41168304/…stackoverflow.com/questions/41741982/…
Michael Freidgeim

36

Tôi đã phải tìm hiểu điều này vì lý do riêng của mình và viết nó lên, vì vậy tôi sẽ đăng những gì tôi học được ở đây ...

Đầu tiên, tôi sẽ trả lời câu hỏi có rủi ro khi nêu rõ điều hiển nhiên: Mã thông báo ID không thể đáng tin cậy và nội dung của nó phải được bỏ qua nếu thời gian hiện tại lớn hơn thời gian đã hết hạn. Câu trả lời của người hỏi nói rằng sau khi xác thực ban đầu của người dùng, Mã thông báo ID sẽ không được sử dụng nữa. Tuy nhiên, vì Mã thông báo ID được bởi nhà cung cấp danh tính, nó chắc chắn có thể hữu ích bất cứ lúc nào để đưa ra cách xác định đáng tin cậy người dùng là ai đối với các dịch vụ khác mà ứng dụng có thể đang sử dụng. Sử dụng ID người dùng hoặc địa chỉ email đơn giản không đáng tin cậy vì nó có thể dễ dàng bị giả mạo (bất kỳ ai cũng có thể gửi địa chỉ email hoặc ID người dùng), nhưng vì Mã thông báo ID OIDC được ký bởi máy chủ Ủy quyền (cũng thường có lợi ích là bên thứ ba) nên nó không thể bị giả mạo và là một cơ chế xác thực đáng tin cậy hơn nhiều.

Ví dụ: một ứng dụng dành cho thiết bị di động có thể muốn cho một dịch vụ phụ trợ biết người dùng đang sử dụng ứng dụng đó là ai và nó có thể cần làm như vậy sau khoảng thời gian ngắn sau khi xác thực ban đầu, lúc đó Mã thông báo ID đã hết hạn và do đó, không thể được sử dụng để xác thực người dùng một cách đáng tin cậy.

Do đó, giống như mã thông báo truy cập (được sử dụng để ủy quyền - chỉ định người dùng có quyền gì ) có thể được làm mới, bạn có thể làm mới Mã thông báo ID (dùng để xác thực - chỉ định người dùng là ai) không? Theo đặc điểm kỹ thuật của OIDC, câu trả lời không rõ ràng. Trong OIDC / OAuth có ba "quy trình" để nhận mã thông báo, quy trình Mã ủy quyền, quy trình ngầm định và quy trình kết hợp (tôi sẽ bỏ qua bên dưới vì nó là một biến thể của hai quy trình còn lại).

Đối với quy trình ngầm định trong OIDC / OAuth, bạn yêu cầu Mã thông báo ID tại điểm cuối ủy quyền bằng cách chuyển hướng người dùng trong trình duyệt đến điểm cuối ủy quyền và bao gồm id_tokengiá trị của response_typetham số yêu cầu. Một phản hồi xác thực thành công theo dòng ngầm là BẮT BUỘC phải bao gồm id_token.

Đối với dòng Mã xác thực , máy khách chỉ định codelàm giá trị của response_typetham số yêu cầu khi chuyển hướng người dùng đến điểm cuối ủy quyền. Một phản hồi thành công bao gồm một mã ủy quyền. Ứng dụng khách thực hiện một yêu cầu đến điểm cuối mã thông báo bằng mã ủy quyền và theo Mục 3.1.3.3 Chính của OIDC. Phản hồi mã thông báo thành công , phản hồi PHẢI bao gồm Mã thông báo ID .

Vì vậy, đối với một trong hai luồng, đó là cách ban đầu bạn nhận được Mã thông báo ID, nhưng làm cách nào để làm mới nó? OIDC Phần 12: Sử dụng Mã thông báo làm mới có tuyên bố sau về Phản hồi mã thông báo làm mới:

Sau khi xác thực thành công Mã làm mới, nội dung phản hồi là Phản hồi mã thông báo của Phần 3.1.3.3 ngoại trừ việc nó có thể không chứa id_token .

có thể không chứa Mã thông báo ID và vì không có cách nào được chỉ định để buộc nó bao gồm mã thông báo ID, bạn phải giả định rằng phản hồi sẽ không chứa Mã thông báo ID. Vì vậy, về mặt kỹ thuật, không có cách nào được chỉ định để "làm mới" Mã thông báo ID bằng mã làm mới. Do đó, cách duy nhất để có được Mã thông báo ID mới là ủy quyền lại / xác thực người dùng bằng cách chuyển hướng người dùng đến điểm cuối ủy quyền và bắt đầu luồng ngầm hoặc luồng mã xác thực như mô tả ở trên. Đặc tả OIDC thêm prompttham số yêu cầu vào yêu cầu ủy quyền để máy khách có thể yêu cầu máy chủ ủy quyền không nhắc người dùng với bất kỳ giao diện người dùng nào, nhưng chuyển hướng vẫn phải xảy ra.


Nếu bạn đang viết một phần mềm chung để làm việc với nhà cung cấp Ủy quyền tùy ý, bạn không thể dựa vào việc trả về id_token khi làm mới. Tuy nhiên nếu bạn đang làm việc với nhà cung cấp cụ thể (chẳng hạn như IdentityServer4), bạn có thể kiểm tra khả năng của nó, và sử dụng id_token nhận được sau khi yêu cầu làm mới
Michael Freidgeim

Vậy làm cách nào để làm mới id_token?
jwilleke

@jwilleke AFAIK, như đã nói ở trên "cách duy nhất để nhận Mã thông báo ID mới là ủy quyền lại / xác thực người dùng bằng cách chuyển hướng người dùng đến điểm cuối ủy quyền"
Scott Willeke

@MichaelFreidgeim Thật thú vị, ý bạn là thông qua cơ chế Khám phá Kết nối ID Mở ? Làm thế nào chính xác để chúng tôi làm điều đó?
Scott Willeke

1
Câu trả lời hay về "nội dung phản hồi của làm mới có thể không chứa id_token". Đã ủng hộ. Nhân tiện, tôi hiểu là các thông số kỹ thuật OIDC không để lại một khoảng thời gian nào cho việc sử dụng Mã làm mới để lấy mã thông báo ID mới: khách hàng có thể làm như vậy bằng cách chỉ định "id_token" làm một trong các phạm vi; nhưng thận trọng chung vẫn được áp dụng ở đây, bởi vì Máy chủ xác thực sẽ đưa ra quyết định cuối cùng về việc có tuân theo phạm vi yêu cầu của bạn hay không.
RayLuo

7

Nếu tôi hiểu đúng, theo điều này và thông số kỹ thuật OpenID Connect Core 1.0 , chính mã thông báo ID có thể được lưu trữ trong cookie như một cơ chế để duy trì các phiên và được gửi với mọi yêu cầu xác thực tới Khách hàng. Sau đó, Khách hàng có thể xác minh mã thông báo ID cục bộ hoặc thông qua điểm cuối trình xác minh của Nhà cung cấp (nếu được cung cấp, giống như Google ). Nếu mã thông báo hết hạn, nó sẽ thực hiện một yêu cầu xác thực khác, ngoại trừ lần này với prompt=nonethông số URL. Ngoài ra, hãy đảm bảo gửi mã thông báo ID đã hết hạn trong id_token_hinttham số, nếu không Nhà cung cấp có thể trả về lỗi.

Vì vậy, prompt=noneviệc Mã thông báo ID hết hạn có vẻ tự nhiên, nhưng đảm bảo Mã thông báo ID mới có thể được lấy một cách suôn sẻ mà không có sự can thiệp của người dùng (tất nhiên là trừ khi người dùng đã đăng xuất khỏi OpenID đó).


6

Nó có cùng mục đích: bạn không thể sử dụng id_tokensau khi nó hết hạn. Sự khác biệt chính là an id_tokenlà một cấu trúc dữ liệu và bạn sẽ không cần gọi bất kỳ máy chủ hoặc điểm cuối nào, vì thông tin được mã hóa trong chính mã thông báo. Một vật thông thường thường access_tokenlà một đồ tạo tác không trong suốt (như GUID).

Người tiêu dùng id_tokenphải luôn xác minh tính hợp lệ (thời gian) của nó.

Tôi không quen 100% với IS, nhưng tôi đoán nó là một lĩnh vực tiện lợi. Bạn nên luôn kiểm tra expxác nhận quyền sở hữu.

Hết hạn chỉ là một trong những xác nhận. id_tokens cũng được ký điện tử và đó cũng là xác nhận bạn phải thực hiện.


Cảm ơn Eugenio. Câu hỏi chính mà tôi có là bạn nên làm gì khi mã thông báo ID hết hạn? Tôi đã nghĩ (có thể sai) rằng để gia hạn mã thông báo truy cập ngắn hạn, bạn HAD để sử dụng mã thông báo làm mới. Nhưng nếu mã thông báo ID có cùng thời hạn sử dụng với mã thông báo truy cập, bạn sẽ ngay lập tức có một mã thông báo ID đã hết hạn, vì vậy việc làm mới mã thông báo truy cập dường như vô nghĩa. Hãy nghĩ rằng tôi có thể thiếu một cái gì đó ở đây!
Appetere

1
Bạn sẽ sử dụng refresh_token (không bị thu hồi) để nhận một access_token hoặc id_token mới. Hoặc đơn giản là người dùng đăng nhập lại. id_tokens về mặt logic tương đương với access_tokens. Chỉ là một định dạng khác.
Eugenio Pace

2
Hiểu biết mới nhất của tôi là khi người dùng có phiên được xác thực với máy chủ ủy quyền, khi mã thông báo truy cập hết hạn chuyển hướng 401 => 302 đến máy chủ ủy quyền sẽ nhận được mã truy cập & mã thông báo ID mới mà không có sự can thiệp của người dùng. Nhưng ở chế độ ngoại tuyến, refresh_token sẽ chỉ trả về một access_token mới cho biết một người dùng cụ thể được phép truy cập một số tài nguyên. Nó không thể trả về id_token, vì điều đó có nghĩa là người dùng cụ thể đã được xác thực và ở chế độ ngoại tuyến thì không phải như vậy.
Appetere

Đây sẽ là một câu trả lời tuyệt vời cho câu hỏi liên quan đến sự khác biệt giữa id_token và access_token (đặc biệt là khi sử dụng mã thông báo không rõ ràng / tham chiếu). Tập trung trả lời câu hỏi trước rồi làm rõ cách sử dụng mã thông báo truy cập và mã thông báo id?
Trent

5

Làm mới mã thông báo có nghĩa là bạn có thể sử dụng lại nó để yêu cầu thứ gì đó từ máy chủ ủy quyền (trong trường hợp này là OP - Nhà cung cấp kết nối OpenID) NGAY CẢ KHI NGƯỜI DÙNG CHƯA ĐĂNG NHẬP. Bạn thường chỉ cho phép điều này đối với các tài nguyên hạn chế và chỉ sau khi người dùng đã đăng nhập và được xác thực ít nhất một lần. Bản thân các mã thông báo làm mới cũng nên bị giới hạn về thời gian.

Trong luồng ngầm định của OIDC, bạn gọi điểm cuối Ủy quyền
và nhận mã thông báo ID trong phản hồi cùng với tất cả các phạm vi và trong đó là tất cả thông tin xác nhận quyền sở hữu.
Các lệnh gọi tiếp theo tới một API được thực hiện với dòng mã .
Luồng ngầm có nghĩa là chỉ kích hoạt ứng dụng javascript hoặc chỉ trình duyệt. Không phải là ứng dụng tương tác với máy chủ.
Vì vậy, ngay cả khi có cách để "làm mới" mã thông báo này, bạn không nên - một cách khôn ngoan về bảo mật - để nó tồn tại quá lâu. Nó sẽ bị đánh cắp và sử dụng lại bởi những người dùng trái phép mạo danh id. Bạn nên buộc đăng nhập mới cho điều đó.

Trong luồng mã, bạn gọi điểm cuối Ủy quyền của OP và nhận mã Ủy quyền (còn được gọi là mã thông báo ủy quyền, viết tắt là authcode). Điều này sẽ hết hạn tương tự như id_token mà bạn đã nhận được trong luồng ngầm, vì những lý do tương tự và không thể và không nên gia hạn.

Giao diện người dùng hoặc ứng dụng của bạn sau đó gọi điểm cuối Mã thông báo của OP và nhận (đôi khi sau khi người dùng đồng ý thêm thông qua giao diện người dùng để cho phép sử dụng tài nguyên thuộc sở hữu của họ trên máy chủ của OP) cả hai:

  • Một id_token, để xác thực - không bao giờ được sử dụng lại trong các cuộc gọi máy chủ, ngoại trừ như một gợi ý trong khi đăng xuất, khi hết hạn của nó không còn quan trọng nữa, và vì vậy, vì những lý do trên nên được để hết hạn và không bao giờ được làm mới.
  • Một access_token - mà sau này, khi gọi một API, có thể được cấp cho điểm cuối UserInfo của OP. Điều đó sẽ trả về các xác nhận quyền sở hữu và API có thể ủy quyền tương ứng.

Bạn có thể làm mới access_token này, vì nó chỉ cho API biết người dùng có yêu cầu gì và tài nguyên nào (theo phạm vi và từng tuyên bố của phạm vi) mà người dùng đồng ý cung cấp cho bạn. Như đã giải thích ở trên, điều này là để cho phép truy cập ngay cả sau khi người dùng không đăng nhập nữa. Tất nhiên bạn không bao giờ muốn cho phép id_token được làm mới, bởi vì bạn không muốn cho phép mạo danh mà không đăng nhập.


2
Những gì bạn đã nói về luồng ngầm một phần không chính xác. Máy khách sử dụng quy trình ngầm định có thể nhận được mã thông báo truy cập ngoài mã thông báo ID và có thể sử dụng mã thông báo truy cập đó để tương tác với máy chủ.
Shaun Luttin

Có một thực tế phổ biến, đó là khi id_token hết hạn, máy khách sẽ yêu cầu mã thông báo mới từ máy chủ, do đó người dùng không cần ủy quyền lại. Ví dụ: xem damienbod.com/2017/06/02/…
Michael Freidgeim

4

Tôi muốn đăng câu trả lời này dưới dạng nhận xét nhưng vì tôi không hoạt động nhiều trên StackOverflow, nên tôi đoán tôi đang đăng nó như một câu trả lời thay thế.

Bạn cũng sử dụng id_tokennhư id_token_hintkhi cố gắng đăng xuất người dùng khỏi một phiên http://openid.net/specs/openid-connect-session-1_0.html . Thành thật mà nói, tôi không nghĩ rằng nó thực sự quan trọng nếu id_tokenhết hạn tại thời điểm này vì bạn chỉ quan tâm đến việc đăng xuất một người dùng cụ thể.


4

TLDR;

Xác thực mã thông báo ID trước khi tin tưởng những gì nó nói.

Thêm chi tiết

Mục đích của thời gian hết hạn mã thông báo ID trong OpenID Connect là gì?

Mục đích là cho phép máy khách xác thực mã thông báo ID và máy khách phải xác thực mã thông báo ID trước các hoạt động sử dụng thông tin của mã thông báo ID .

Từ thông số Dòng ngầm định của OpenID :

Nếu bất kỳ quy trình xác thực nào được xác định trong tài liệu này không thành công, bất kỳ hoạt động nào yêu cầu thông tin không xác thực chính xác PHẢI bị hủy bỏ và thông tin không xác thực được PHẢI KHÔNG được sử dụng.

Để chứng thực điều đó, tài liệu OpenID Connect của Google cho biết điều này về xác thực mã thông báo ID:

Một điều làm cho mã thông báo ID trở nên hữu ích là thực tế là bạn có thể chuyển chúng xung quanh các thành phần khác nhau của ứng dụng của mình. Các thành phần này có thể sử dụng mã thông báo ID làm cơ chế xác thực nhẹ xác thực ứng dụng và người dùng. Nhưng trước khi bạn có thể sử dụng thông tin trong mã thông báo ID hoặc dựa vào nó như một xác nhận rằng người dùng đã xác thực, bạn phải xác thực nó.

Vì vậy, nếu ứng dụng khách của chúng tôi sẽ thực hiện một số hành động dựa trên nội dung của mã thông báo ID, thì chúng tôi phải xác thực lại mã thông báo ID.

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.