首页 > 解决方案 > OIDC - 获取一个身份令牌以供运行计划作业的后端(非实际用户)服务使用

问题描述

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

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

系统图

我们已经研究了这些选项:

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

什么是最好的选择?

标签: oauth-2.0identityserver4openid-connectjwt-authpingfederate

解决方案


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

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

Authorization: basic bXktZ29vZC1zZXJ2aWNlOkY2M0JEOTkyLTMzNTUtNDYzNi1CNzFBLTM3RDg0QzI3ODEzRQo=

然后,继续验证您从 SPA 获得的 ID 令牌。我假设您使用 RFC 6750 中描述的技术将其发送到 API:

Authorization: bearer eyJhbGciOiJSUzI1NiJ9.ey...

因此,这两种不同的身份验证方法使 API 可以轻松判断谁在调用它。更重要的是:它应该很容易实现,即使授权发生了变化。这应该有望让您扑灭大火,然后在更基本的层面上解决问题。

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

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

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

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

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

我会推荐以下高级架构文档和视频。随着您继续发展您的实施,这些将有所帮助:


推荐阅读