oauth2.0 关于id_token与access_token的说明

xe55xuns  于 12个月前  发布在  其他
关注(0)|答案(5)|浏览(173)

我正在使用OIDC和OAuth 2.0(使用Auth 0)构建一个系统,我不确定如何正确使用id_tokenaccess_token。或者说,我对在我的设置中为各种服务分配哪些角色感到困惑。
我有一个完全静态的前端应用程序(单页应用程序,HTML + JS,没有后端),它确保用户使用Auth 0的隐式流进行身份验证。前端应用程序然后从我正在构建的API中获取数据。
哪一个是对的?

  • 前端SPA是OAuth客户端应用程序
  • 我的API服务是OAuth资源服务器

. or:

  • 前端和我的API服务都是客户端应用

如果我的前端和后端API都可以被认为是客户端,我认为在从前端到后端的请求中使用id_token作为承载令牌没有什么真实的的危害-这很有吸引力,因为这样我就可以简单地在后端验证签名的令牌,并且我有我需要的关于用户的所有信息。但是,如果我的API被认为是资源服务器,我可能应该使用access_token,但这样我就必须在每个API请求时连接到Auth 0的服务器,以验证令牌并获得基本的用户信息,不是吗?
我读过this,它似乎表明access_token是与我的API一起使用的唯一有效令牌。但就像我说的,我不确定各个服务的角色。使用id_token是诱人的,因为它不需要后端的网络连接,并且包含提取正确数据所需的信息。
什么是正确的方式去做这件事?

zbwhf8kr

zbwhf8kr1#

我喜欢这篇关于差异的中等文章,都归功于这位作者。
https://medium.com/@nilasini/id-token-vs-access-token-17e7dd622084
如果你像我一样使用Azure AD B2C,你可以在这里阅读更多:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/openid-connect

ID Token

如果你使用scope作为openid,你会得到id token。Id token是特定于openid scope的。使用openid scope你可以得到id token和access token。
OpenID Connect对OAuth 2.0的主要扩展是ID Token数据结构,它允许最终用户进行身份验证。(声明是包含有关用户信息的名称/值对)有关使用客户端时授权服务器对最终用户的身份验证,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中编码的声明中,有一个过期(exp),它必须作为验证过程的一部分。此外,JWT的签名部分与一个密钥一起使用,以验证整个JWT没有被篡改。

访问令牌

访问令牌用作不记名令牌。不记名令牌意味着持有者(持有访问令牌的人)可以访问授权资源而无需进一步识别。因此,保护不记名令牌非常重要。如果我可以以某种方式获得并“持有”您的访问令牌,我可以假装为您。
这些令牌通常具有较短的生命周期(由其到期决定)以提高安全性。也就是说,当访问令牌到期时,用户必须再次进行身份验证以获得新的访问令牌,从而限制了它是承载令牌的事实的暴露。
虽然OIDC规范没有强制要求,但Okta使用JWT作为访问令牌,因为(除其他事项外)过期是内置在令牌中的。
OIDC指定一个/userinfo端点,该端点返回身份信息并且必须受到保护。提供访问令牌使该端点可访问。
https://connect2id.com/learn/openid-connect#cool-id-token-uses https://developer.okta.com/blog/2017/07/25/oidc-primer-part-1

xcitsw88

xcitsw882#

您的前端是您的OAuth客户端应用程序,一旦它存储了令牌,它就可以对OAuth流采取行动。而您的API服务是资源服务器,因为它接受身份服务器颁发的access_token。
我还要说的是,你的id_token代表登录用户的身份,可能包含应用程序的敏感数据。access_token代表你访问资源的凭证。
最后,您将使用access_token来请求资源,然后如果您需要登录用户(资源所有者)的特定数据,则可以从token端点请求ID token。

bcs8qyzn

bcs8qyzn3#

在我看来,第一种方法是正确的,SPA是客户端应用程序,API是资源服务器。
我建议您将id_token的使用限制在您的SPA中。您可以使用id token中的基本信息(如用户名和电子邮件)在UI中显示用户信息。如果您也可以将访问令牌生成为JWT,则您的API可以验证访问令牌,而无需转到身份提供程序。您可以包含角色(或类似)以获取访问令牌中的授权信息。

ie3xauqp

ie3xauqp4#

我还想知道如果我使用从IdP接收的令牌,是否需要在每个请求时都与IdP对话。我最终进行了以下设置:

  • 只有后端与IdP对话,前端不与IdP对话。
  • 在IdP回调时,后端会为前端发出一个JWT。
  • 用户会话和前端-后端通信完全由我的应用使用JWT令牌管理。

标签:OAuth2 in NestJS for Social Login (Google, Facebook, Twitter, etc)
这个repo:https://github.com/thisismydesign/nestjs-starter
问题:OAuth2 flow in full-stack NestJS application

hrirmatl

hrirmatl5#

id_token是用于身份验证的加密编码令牌。OP(授权提供者)是生成它的人,RP(依赖方或资源)最终将在客户端移交时将令牌重新呈现给OP以进行反验证。简而言之,id_tokenauthn工作流绑定。
access_token启用资源访问。它会子化userinfo,即id_token或代表其请求访问的任何其他主体。因此,此令牌包括用户声明以及对授权组的声明。简而言之,access_token与您的authz工作流绑定。

相关问题