簡體   English   中英

澄清 id_token 與 access_token

[英]Clarification on id_token vs access_token

我正在使用 OIDC 和 OAuth 2.0(使用 Auth0)構建一個系統,但我不確定如何正確使用id_tokenaccess_token 或者更確切地說,我對在我的設置中為各種服務分配哪些角色感到困惑。

我有一個完全靜態的前端應用程序(單頁應用程序,HTML + JS,無后端),可確保使用針對 Auth0 的隱式流對用戶進行身份驗證。 然后前端應用程序從我也在構建的 API 中獲取數據。

現在,哪個是對的?

  • 前端 SPA 是 OAuth客戶端應用程序
  • 我的 API 服務是 OAuth資源服務器

...或者:

  • 前端和我的 API 服務都是客戶端應用程序

如果我的前端和后端 API 都可以被認為是客戶端,我認為在id_token后端的請求中使用id_token作為承載令牌並沒有真正的危害——這很有吸引力,因為這樣我就可以簡單地驗證簽名的令牌后端,我有我需要的用戶的所有信息。 但是,如果我的 API 被視為資源服務器,我可能應該使用access_token ,但是我必須在每個 API 請求上連接到 Auth0 的服務器,以驗證令牌並獲取基本用戶信息,不是嗎?

我讀過似乎表明access_token是與我的 API 一起使用的唯一有效令牌。 但就像我說的,我不確定各個服務的角色。 使用id_token很誘人,因為它不需要后端的網絡連接,並且包含提取正確數據所需的信息。

解決這個問題的正確方法是什么?

您的前端是您的 OAuth 客戶端應用程序,一旦它存儲了令牌,它就可以對 OAuth 流執行操作。 而你的 API 服務是資源服務器,因為它接受你的身份服務器發出的 access_token。

另外我想說的是,您的 id_token 代表登錄用戶的身份,可能包含您的應用程序的敏感數據。 access_token 是您訪問資源的憑證。

最后,您將使用 access_token 來請求資源,然后如果您需要來自登錄用戶(資源所有者)的特定數據,您可以從令牌端點請求 ID 令牌。

在我看來,第一種方法是正確的。 您的 SPA 是客戶端應用程序,您的 API 是資源服務器。

我建議您將 id_token 的使用限制在您的 SPA 之前。 您可以使用 id 令牌中的基本信息(如用戶名和電子郵件)在您的 UI 中顯示用戶信息。 如果您也可以將訪問令牌生成為 JWT,那么您的 API 可以驗證訪問令牌,而無需轉到身份提供者。 您可以在訪問令牌中包含角色(或類似角色)以獲取訪問令牌中的授權信息。

我喜歡這篇關於不同之處的 Medium 帖子,這一切都歸功於這位作者。

https://medium.com/@nilasini/id-token-vs-access-token-17e7dd622084

如果您像我一樣使用 Azure AD B2C,可以在此處閱讀更多信息:

https://docs.microsoft.com/en-us/azure/active-directory-b2c/openid-connect

身份令牌

如果您使用范圍作為 openid,您將獲得 id 令牌。 Id 令牌特定於 openid 范圍。 使用 openid 范圍,您可以獲得 id 令牌和訪問令牌。

OpenID Connect 對 OAuth 2.0 進行的主要擴展是 ID 令牌數據結構。 ID 令牌是一個安全令牌,其中包含有關授權服務器在使用客戶端時對最終用戶進行身份驗證的聲明(聲​​明是包含有關用戶信息的名稱/值對),以及可能的其他請求聲明。 ID 令牌表示為JSON Web 令牌 (JWT)

{
   "iss": "https://server.example.com",
   "sub": "24400320",
   "aud": "s6BhdRkqt3",
   "nonce": "n-0S6_WzA2Mj",
   "exp": 1311281970,
   "iat": 1311280970,
   "auth_time": 1311280969,
   "acr": "urn:mace:incommon:iap:silver"
}

以上是默認的 JWT 聲明,除此之外,如果您向服務提供商請求聲明,那么您也將獲得這些聲明。

根據 OIDC 規范, id_token是 JWT。 這意味着:

  • 有關用戶的身份信息被直接編碼到令牌中,並且
  • 可以明確地驗證令牌以證明它沒有被篡改。

規范中有一組用於驗證id_token規則 id_token編碼的id_token有一個到期 ( exp ),它必須作為驗證過程的一部分予以尊重。 此外,JWT 的簽名部分與密鑰一起使用,以驗證整個 JWT 沒有以任何方式被篡改。

訪問令牌

訪問令牌用作不記名令牌。 持有者令牌意味着持有者(持有訪問令牌的人)可以訪問授權資源而無需進一步識別。 因此,保護​​不記名令牌很重要。 如果我能以某種方式獲得並“持有”您的訪問令牌,我可以假裝成您。

這些令牌通常具有較短的生命周期(由其到期決定)以提高安全性。 也就是說,當訪問令牌過期時,用戶必須再次進行身份驗證以獲取新的訪問令牌,以限制其是不記名令牌這一事實的暴露。

盡管 OIDC 規范沒有強制要求,但 Okta 使用 JWT 來訪問令牌,因為(除其他外)過期時間直接內置於令牌中。

OIDC 指定了一個 /userinfo 端點,該端點返回身份信息並且必須受到保護。 提供訪問令牌使端點可訪問。

http://openid.net/specs/openid-connect-core-1_0.html https://connect2id.com/learn/openid-connect#cool-id-token-uses https://developer.okta.com/博客/2017/07/25/oidc-primer-part-1

我還想知道,如果我使用從 IdP 收到的令牌,是否需要在每次請求時都與 IdP 交談。 我最終得到了以下設置:

  • 只有后端與 IdP 對話,前端不會。
  • 在 IdP 回調后,后端會為前端發出 JWT。
  • 用戶會話和前端-后端通信完全由我的應用程序使用 JWT 令牌進行管理。

查看這篇文章: NestJS 中的 OAuth2 用於社交登錄(Google、Facebook、Twitter 等)

和這個回購: https : //github.com/thisismydesign/nestjs-starter

這個問題: OAuth2 flow in full-stack NestJS application

id_token是用於身份驗證的加密編碼令牌。 OP(身份驗證提供者)是生成它的那個,而 RP(依賴方或資源)最終會將令牌重新呈現給 OP,以在客戶端移交令牌時進行反驗證。 簡而言之, id_tokenauthn工作流程相關聯。

access_token啟用資源訪問。 它確實包含用戶信息,即id_token或代表其請求訪問的任何其他主體。 因此,此令牌既包括用戶聲明,也包括對已授權組的聲明。 簡而言之, access_token與您的authz工作流程相關聯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM