为啥我不应该在 IDP 上下文中使用 IdToken 作为不记名令牌?

Posted

技术标签:

【中文标题】为啥我不应该在 IDP 上下文中使用 IdToken 作为不记名令牌?【英文标题】:Why shouldn't I use IdToken as bearer token in an IDP context?为什么我不应该在 IDP 上下文中使用 IdToken 作为不记名令牌? 【发布时间】:2021-01-02 05:04:54 【问题描述】:

我正在使用 IDP 平台(此处为 AWS Cognito,但可能是 Auth0、OKTA 或 Keycloak),我想知道为什么不鼓励我使用 ID Token 作为授权令牌。

更具体地说,我不会使用从用户授权委托给第三方应用程序的资源服务器。我的 IDP 只会让我在我的不同应用程序上对所有用户进行 SSO。这里没有授予范围,只有身份验证声明每个服务将用于授予或拒绝对资源(如电子邮件、用户 ID 或角色)的访问权限。

我知道我可以为我的应用程序提供id token,然后为我的用户创建一些会话。既然可以在每个应用程序的后端检查其签名,为什么我不应该将 id token 本身用作无状态会话令牌?

如果我应该id token 上使用access token - 我可以用角色替换作用域吗?或者我应该如何理解非委托上下文中的范围(“用户自己使用应用程序,未授予权限”与“用户将所有范围提供给本身就是应用程序的 SPA 前端”)

顺便说一句,我正在通过前端的代码 PKCE 流恢复令牌。

【问题讨论】:

【参考方案1】:

ID 令牌仅包含有关用户以及用户如何进行身份验证的详细信息。因此它非常适合与用户创建更持久的 cookie 会话。 ID-token 的默认生命周期也很短,比如分钟。您通常在建立 sesson 后丢弃 id-token。您永远不应该将 ID 令牌传递给其他服务。

访问令牌旨在让您访问令牌所针对的 API。

当用户登录时,您请求访问某些范围和用户选择(同意)的范围,然后包含在访问令牌中(如范围和受众声明)。

理论上,您可以将 ID 令牌传递给 API,而不是它应该如何工作。 请参阅this 和this 了解更多详情:

【讨论】:

好的。但是现在如果我使用 id-token 作为无状态的 sesison 令牌,持续几分钟就可以了(访问令牌不再持续),并定期调用刷新令牌。在这种情况下,请记住我没有将 id-token 发送到任何第三方服务,而是使用它来从我的前端到后端进行身份验证。听起来是不是太糟糕了?如果是这样,为什么? 好的,我知道第一个链接,即使:Do not use ID tokens to gain access to an API. ... the audience of the ID ... must be the client ID of the application making the authentication request. If this is not the case, you should not trust the token. 并且我确实将 id 令牌发送给客户端,请求它使用正确的 id。所以我不明白为什么要气馁。但如果是这样,您将如何让应用程序通过用户定义的角色来管理授权? ID-token 可以包含个人信息,如姓名、地址、电子邮件..(如驾驶执照/护照),但您不想将其提供给第三方和 API,而是就像在酒店一样,您会得到一个用于访问资源的密钥。你不使用你的身份来访问东西.... 除非服务本身使用身份授权,比如你去邮局用身份证取包裹。身份验证让他们授权您。就我而言,我的 API 是第一方。我的客户应该获得完整的访问权限,API 将根据用户 ID 和角色管理授权。实际上,我认为那些可以进入访问令牌 - 但不能使用 AWS Cognito,这可能是我困惑的根源 - 因为它们不完全遵循标准并鼓励将 Id 令牌作为授权方法。

以上是关于为啥我不应该在 IDP 上下文中使用 IdToken 作为不记名令牌?的主要内容,如果未能解决你的问题,请参考以下文章

WPF:为啥我不应该在 ControlTemplate 中使用 TemplateBinding Margin - Margin 是不是仅适用于元素的容器?

为啥我不应该使用 catch() 来处理 React useEffect API 调用中的错误?

为啥我不应该在访问对象之前使用“if Assigned()”?

UISplitViewController:为啥我不应该在导航或标签栏界面中显示它?

为啥我不应该使用 Unity?

没有来自 IDP 的 IDP 元数据