OIDC - 获取身份令牌以供后端(无实际用户)服务使用 运行 计划作业

OIDC - Obtaining an Identity Token for use by a backend (no actual user) service running scheduled jobs

我们有一个 API(实际上是几个微服务)由 OIDC 保护。授权服务器由我们的客户(非我们内部)拥有和管理,并为我们的 SPA 提供身份令牌。该 SPA 然后将该身份令牌传递给我们的后端服务器,该服务器验证令牌,提取 SubjectId(用户),然后在内部数据库中查找他们的角色。我们没有使用令牌进行授权(意味着我们忽略声明),它仅用于身份验证。

我们有一个在安全环境中运行的后端 Windows 服务(因此它可以安全地存储秘密)需要调用相同的 API。为了调用 API,它需要一个 OIDC 身份令牌来提供身份验证。安全地执行此操作的最佳方法是什么?

我们查看了这些选项:

  1. Username/Password Flow (OIDC) - 我们拒绝了它,因为它已被弃用。这使得它不是新代码的可靠选择,而且,我们不能确定我们的客户现在和将来是否允许使用它。
  2. 客户端凭据流 (OIDC) - 我们尝试了这个...但它只提供没有身份令牌的访问令牌。我们的全部要求是一个身份令牌(因为我们用它来查找我们系统中的角色)...所以这似乎不是一个选项。
  3. 我看了这篇文章:https://nordicapis.com/how-to-handle-batch-processing-with-oauth-2-0/ 很有趣。我可以设置一个非过期(或非常长)的身份令牌,仅限于一个流或另一个......但需要我托管和 OIDC 服务器或管理他们的。我们的客户不会授予访问权限。
  4. Martin Fowler 写了一篇关于为此目的使用刷新令牌的文章:https://martinfowler.com/articles/command-line-google.html这有两个问题:它是针对 Auth 而不是 OIDC...所以它不处理身份令牌。应该工作,但好奇它是否已经完成。另外,就我而言,刷新令牌过期时没有人刷新...我需要一些不会过期或可以由后端服务自动刷新的东西。

最好的选择是什么?

不太确定您的用例,但在我看来,我可能会做这样的事情:

SPA 根本不处理令牌,而是只给它一个会话 cookie。让一切都更加安全。

让服务调用 OIDC 服务器以获取其自己的访问令牌,该令牌可以包含调用 API 所需的必要子声明或角色声明。

首先让我说,我不会推荐你的架构。所以,我会给你两个答案:一个是短期的实用的,一个是中期的,会产生一个更理想的系统。

首先,快速修复:在 API 中打开基本身份验证。然后,使用基本身份验证和长密码从计划任务运行程序调用您的 API,如下所示:

Authorization: basic bXktZ29vZC1zZXJ2aWNlOkY2M0JEOTkyLTMzNTUtNDYzNi1CNzFBLTM3RDg0QzI3ODEzRQo=

然后,继续验证您从 SPA 获得的 ID 令牌。我假设您使用 RFC 6750:

中描述的技术将其发送到 API
Authorization: bearer eyJhbGciOiJSUzI1NiJ9.ey...

因此,这两种不同的身份验证方法使 API 可以轻松分辨谁在调用它。更重要的是:它应该 容易 实施,即使授权更改。这应该有望让你扑灭大火,然后在更基本的层面上解决问题。

当你达到这一点时,我建议你做两件事:

  1. 添加您自己的令牌服务(即授权服务器)。 API 应该只信任它自己的授权服务器,而不是某个外国的。这将形成一个枢轴点,这是您现在需要但没有的。

  2. 只接受您 API 中的访问令牌。 APIs 应该只使用访问令牌。如果 API 接受 ID 令牌,它有 99% 的可能性做错了。

SPA 是您照片中唯一需要 ID 令牌的。它应该得到 and 一个访问令牌。更重要的是,它应该从 您的 OpenID Connect 提供商 (OP) 而不是您的客户那里获得。这应该反过来为您的客户执行 OpenID Connect,但通常会处理身份验证,以便您的应用程序将来可以处理其他身份验证要求,而无需更改 SPA。此外,其他应用程序可以重复使用所有这些。

SPA(和调度服务)应将访问令牌发送到 API。令牌(或它的 phantom or split form)应至少包含主题 ID,以便它可以获得授权调用所需的更多信息。这应该来自您的令牌服务(即您的新 OP,因为它将执行 OAuth 和 OIDC)。

我会推荐以下高级架构文档和视频。这些将有助于您继续改进您的实施: