【问题标题】:OpenID Connect : Is it fine to use id_token as access_token?OpenID Connect:使用 id_token 作为 access_token 可以吗?
【发布时间】:2018-01-15 19:47:23
【问题描述】:

在我工作的一个应用程序中,我们正在考虑仅将 id_token 用于所有用例,包括身份验证和授权。该解决方案目前正在从头开始开发。目前没有任何资源的消费者,我们可以修改资源以使用 id_token。我对 openid_connect 和 oauth 2.0 的概念有点陌生。仅使用具有所有访问详细信息的 id_token 会有任何问题吗?

【问题讨论】:

    标签: oauth-2.0 openid-connect


    【解决方案1】:

    如果您的应用程序只需要对用户进行身份验证,然后让他们使用他们可能访问的所有功能访问其后端,那么仅使用 ID 令牌并根据用户名或角色检查访问权限会更容易。仅使用 ID 令牌时,您还可以接受来自不同 OAuth2 提供者的 ID 令牌。

    访问令牌对于部分访问委派很有用 - 当用户将他们的一些权限委派给另一个应用程序时。例如,如果我创建了一个应用程序,要求其用户对其 GMail 进行只读访问,则该应用程序可以获得访问权限,而无需访问用户的任何其他 Google 资源。

    如果您想为一个简单的客户端应用程序及其后端使用访问令牌,您的客户端应用程序会询问它可能使用的所有 OAuth2 范围,然后查看从 OAuth2 获取的访问令牌中返回的范围服务器。

    因此,如果您只想为其前端创建后端 API,并且不打算为其他应用程序打开它,那么仅使用 ID 令牌会更容易。如果您发现需要访问令牌,您可以稍后开始使用它们。

    您还可以考虑根据提供的 ID 令牌发布您自己的令牌 (JWT),其中包含您需要的所有身份验证和授权信息,这样您的后端就不必在每次 API 访问时获取用户的安全数据。

    【讨论】:

    • 感谢简。该案例正是使用 gmail 和其他资源的示例所提到的。类似的资源存在于我们的生态系统中,被除我们之外的其他应用程序访问。关键是资源是否可以设计为仅依赖于 id_token;以及附加到 id_token 的细粒度权限/访问权限。我试图回答的另一个问题是——拥有两个令牌有什么好处?为什么不能将其组合在一个令牌中?除了存储的数据类型之外,id_token 和 access_token 之间是否有任何资金差异?
    • 在 OpenID Connect 中引入了 ID 令牌,用于身份验证。如果您想委派访问权限,访问令牌正是为此而设计的——用户同意将他们的一些权限传递给应用程序。如果您以包含范围的方式构建您的 ID 令牌(与访问令牌相同的方式),那么您正在创建一个新协议。您不需要在应用程序之间传递 ID 令牌 - 它们应该只证明用户的身份。如果一个应用程序 A 调用应用程序 B,那么 A 是调用者,而不是最初调用 A 的用户。
    • 感谢@Ján 的回复。 “您不应该需要在应用程序之间传递 ID 令牌 - 它们 应该只证明用户的身份” - 当你说它们时 - 应用程序 B(资源服务器)是否需要使用 access_token 证明用户的身份?如果是,假设 access_token 没有身份信息怎么办。
    • 我的意思是 ID 令牌。顺便说一句,您也可以从访问令牌中获取用户名 - 使用自省端点。您还可以查看 OAuth 2.0 Token Exchange RFC,这对您来说可能很有趣。许多 OAuth2+微服务讨论涉及在多个服务中传递令牌。
    • 谢谢。我怀疑许多自定义/企业软件场景将遵循这种模式,您需要代理或通过 authentication 从应用程序的一个组件到另一个组件。您不是在处理 OAuth2 意义上的 authorization 。用户并未授权组件 1 代表用户对组件 2 进行 API 调用,而是组件 1 和组件 2 在用户看来都像是一个单独的应用程序。
    【解决方案2】:

    我建议按照设计的 OIDC 规范(即,使用 access_token 而不是 id_token 进行资源服务器授权)以防止自己面临安全漏洞。

    这里有一个关于使用 id_token 作为 access_token 的很好的讨论:https://github.com/IdentityServer/IdentityServer3/issues/2015#issuecomment-147527823

    该规范是为在客户端使用的 id 令牌和 要在 API 上使用的访问令牌。我相信你能想出 一些替代协议来重用 id 令牌,但 OAuth2 和 OIDC 只是没有那样发展。我确定它们是否都是从 从头开始,它们看起来会有所不同。

    至于“将 id 令牌传递到后端是否安全”——不确定。一世 真的没有仔细研究针对它的攻击或它是如何发生的 被操纵或被愚弄。规范作者会做那种事情,并且 这就是为什么我们倾向于坚持他们的领先优势,因为他们已经花费了很多 比我有更多的时间。

    问题,为什么要使用 id_token 而不是 access_token?获取真正的 access_token 很容易,为什么要违反规范?

    更新:

    如果您确实允许在资源服务器上使用 id_token(请注意),您需要将允许调用您的 API 的每个客户端“受众”列入白名单,除非您希望任何通过您的提供商身份验证的应用程序调用您的API!同样,我建议您遵循规范,否则您将在可靠指导的真空中制造安全漏洞。

    【讨论】:

    • 感谢@sdoxsee。实际上,使用的 IDP 是供应商产品,不允许在 access_token 中添加自定义声明。但它确实允许自定义 id_token。另外,我浏览了您分享的链接。我完全理解 id_token 和 access_token 背后的概念。唯一的困惑是 - 拥有两个令牌但关注点分离是否有任何显着优势?另外,您提到了安全漏洞 - 我无法从您共享的链接中获得更多详细信息。但它应该与 access_token 的传输方式不同。我错过了什么吗?
    • 我只提到安全漏洞,只是因为它违反了规范(以及所有与自己的安全相关的风险)。我自己没有看到任何使用 id_token 进行授权的漏洞,但我还没有考虑清楚。事实上,我记得读过(目前找不到链接),规范团队在是否应该使用一个或两个令牌方面存在一些分歧。它本可以采取任何一种方式,但他们选择了这两个令牌。您使用的是什么供应商 OP?很惊讶它不支持自定义声明。
    • 感谢@sdoxsee 的回复。在我们的应用程序中使用的是销售人员身份。这不是一个成熟的 OP。
    • 我相信这是对规范的狭义解释。虽然混淆客户端不一定是 FE,但它可以是应用程序(包括 FE/BE,在某些情况下甚至是基于 api 的数据库)。访问令牌用于委托,用户同意访问他们的数据。但是,如果您在应用程序中登录用户,则无需同意,用户可以访问自己的数据。也就是说,许多 IDP 仍然以 OAuth 术语思考并强迫您使用访问令牌(例如,有些不允许您刷新 ID 令牌)。 Imo Ján Halaša 的建议是正确使用 OpenID ID 令牌。
    • Brecht De Rooms,Ján Halaša 的建议“可能”是合理的,如果你有一个像他描述的那样简单的场景。我看到的问题是“您如何在资源服务器 API 上验证受众声明?” id_token 的受众是请求令牌的客户端,而不是后端 API。如果您不在 API 上验证受众,那么任何令牌(包括颁发给其他客户端的令牌)都将被接受。为了安全起见,您需要为每个调用您的资源服务器的客户端验证“n”个受众。对于这种简单的场景,您应该在 API 上验证客户端的受众。
    【解决方案3】:

    所有授权都是本地的。这意味着具有要共享资源的服务器需要具有信息来决定是否释放资源。所以问题是; id_token 是否有足够的信息以及所需的保证级别来进行授权。这是这里唯一真正的问题。

    【讨论】:

      猜你喜欢
      • 2013-10-18
      • 2019-10-15
      • 2018-04-25
      • 1970-01-01
      • 2020-12-16
      • 2019-03-04
      • 2020-11-03
      • 1970-01-01
      • 2020-11-20
      相关资源
      最近更新 更多