【问题标题】:OpenID Connect/Oauth2 - cache/use tokensOpenID Connect/Oauth2 - 缓存/使用令牌
【发布时间】:2021-03-11 01:35:31
【问题描述】:

我有一个带有 REST API 的系统。 REST API 的用户应该能够使用 OpenID Connect over Oauth2 进行身份验证。系统本身有自己的权限系统。我需要将 IDPs 用户映射到我的本地权限系统。我正在考虑将本地数据库中的 openid 范围 sub 键保存为唯一的用户标识符。

但是我应该在 API 中将哪个令牌返回给用户。它应该是来自 OpenID Connect 层的 oauth2 访问 id 还是 token_id,还是两者兼而有之?

所以我为 API 的最终用户看到了这些替代方案:

Authorization: Bearer <access_id>
Authorization: Bearer <token_id>
Authorization: Bearer <access_id>
TokenID: <token_id>

如果不将 token_id/access_id 保留在系统中,我需要根据 API 请求从客户端获取此信息。令牌 ID 包含 JWT 声明(子),因此我需要它来验证客户端可以在我的系统中执行的操作。

我是否需要将以下任何 ID 存储在我的本地数据库中以验证 API 请求,还是应该由用户提供?

  • 刷新令牌?
  • 访问令牌?
  • 令牌 ID?

我基本上是在身份验证和用户识别之后。我不是在访问除此之外的任何外部资源之后。

最后一个问题。我是否需要验证对 IDP 的每个请求的访问令牌还是可以缓存它?使用 OpenID Connect 时是否需要同时验证访问令牌和令牌 ID?

编辑:

我的系统本身有一个 REST API 和它自己的权限系统。权限系统使用任何使用 OpenID Connect 的身份验证系统提供的用户 ID。第一个用户是手动添加到权限系统的。

思路:

  1. 我的系统用户请求https://mysystem/login
  2. 用户被重定向到https://idp/auth
  3. IDP 将成功登录重定向到https://mysystem/callback 我的系统从令牌 ID JWT 获取用户 ID (sub) 和电子邮件。
  4. 然后使用访问令牌(不是 OIDC 令牌 ID)返回给用户。
  5. 用户现在可以执行: curl -H "Authorization: Bearer 访问令牌”https://mysytem/some/resource
  6. Mysytem 从用户那里得到这个请求,但不知道如何将访问令牌映射到数据库中的用户 ID,而无需向 IDP 询问用户 ID。

我想使用外部 IDP 让用户登录,而不是从 3rd 方系统访问资源。

【问题讨论】:

    标签: rest oauth oauth-2.0 openid openid-connect


    【解决方案1】:

    更新

    访问令牌确实有用户 ID - 请参阅 step 14 of this write up。为什么你认为没有?

    此规则的一个例外是当没有用户参与时 - 用于应用程序之间的通信(例如客户端凭据流)。但你没有使用它。

    原始答案

    您应该只将完整的访问(持有者)令牌从 UI 发送到 API - 您不需要在数据库中存储令牌详细信息。

    迁移到 OAuth 架构时,您会将用户数据存储在 2 个位置:

    • 您的普通产品数据库 - 通常包括角色和用户权限
    • 授权服务器 - 生成唯一的用户 ID

    按照您的建议,将唯一用户 ID 存储在产品数据中以进行关联和跟踪是很常见的。登录后,您的 API 通常需要根据产品数据进行授权。

    我的几篇博文更详细地介绍了这些主题:

    我的博客还链接到sample code,将这些概念联系在一起。

    【讨论】:

    • 所以我的权限系统与来自 IDP 的用户 ID 相结合。但是我如何将访问令牌(在 API 请求中的承载中给出)映射到我数据库中的用户?或者我是否需要为每个请求查找 /userinfo 以获取 sub ID 以映射到我的数据库?我只是不明白如何将访问令牌映射到数据库中的用户。
    • 如果您有现有用户,通常会在用户首次完成登录时通过电子邮件在 OAuth 数据和产品数据之间进行匹配。当我迁移产品时,我已经这样做了,并将注册电子邮件作为迁移的先决条件。
    • 我可能有点不清楚。我没有现有用户。我希望用户 ID 通过 oauth2 来自 Openid Connect。假设有这样的场景:1.) 用户向我的 REST API 请求 /api/login 2.) 我重定向到 OpenID/Oauth2 端点进行身份验证 3.) 我取回令牌 ID/访问 ID。我从令牌 ID 和电子邮件中获取 UID。 4.) 我将访问令牌作为 API 响应返回给用户 5.) 带有承载的用户请求 /api/some/resource: 6.) 我的 REST API 接收到带有访问令牌的 /api/some/resource 的请求。最后一步,6.如何将访问令牌映射到用户?
    • 您的 API 需要执行以下操作: 1. 首先验证令牌。然后 2. 读取令牌的唯一用户 ID(通常是“子”声明)。然后 3. 在 API 数据库的用户表中查找该用户 ID。然后是 4a。如果找到查找用户的权限。如果未找到,则 4b 以默认权限将新行插入用户表中。然后 5. 运行 API 授权以强制执行权限。
    • 一个更有趣的问题是权限如何管理以及由谁管理。也许管理员需要在用户第一次登录之前在您的 API 数据库中设置这些。如果是这样,则不应允许如上所述自动创建用户,如果未找到令牌中的用户,您的应用程序应显示未经授权的错误。如果您可以解释如何设置权限,我可以提供进一步的建议。这不仅仅是一个技术问题 - 您可能需要设计一个安全的入职流程。
    猜你喜欢
    • 2014-05-02
    • 2016-06-26
    • 2015-08-28
    • 2014-12-03
    • 2018-05-06
    • 2018-10-20
    • 2023-03-18
    • 2018-04-16
    • 2018-12-28
    相关资源
    最近更新 更多