关于oauth 2.0:关于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作为承载令牌时,我认为并没有真正的危害-这很有吸引力,因为这样我就可以验证后端上的签名令牌,我便拥有了所需用户的所有信息。但是,如果我的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可以验证访问令牌,而无需使用身份提供者。您可以在访问令牌中包含角色(或类似角色),以在访问令牌中获取授权信息。


我喜欢这篇有关差异的中型帖子,所有内容都感谢该作者。

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

如果您像我一样使用Azure AD B2C,则可以在此处阅读更多信息:

https://docs.microsoft.com/zh-cn/azure/active-directory-b2c/openid-connect

ID令牌

如果将范围用作openid,则将获得id令牌。 id令牌特定于openid范围。使用openid作用域,您可以同时获取id令牌和访问令牌。

OpenID Connect对OAuth 2.0进行的主要扩展(用于使最终用户能够通过身份验证)是ID令牌数据结构。 ID令牌是一种安全令牌,其中包含与使用客户端时授权服务器进行的最终用户身份验证有关的Claims(声明是包含有关用户信息的名称/值对),并可能包含其他请求的Claims。 ID令牌表示为JSON Web令牌(JWT)

1
2
3
4
5
6
7
8
9
10
{
  "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端点,该端点返回身份信息并且必须受到保护。呈现访问令牌使端点可访问。

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