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

Dav*_*rtz 4 oauth-2.0 jwt pingfederate openid-connect identityserver4

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

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

系统图

我们研究了这些选项:

  1. 用户名/密码流 (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...所以它不处理带有身份令牌。应该可以,但很好奇是否已经完成。另外,就我而言,刷新令牌过期时没有人刷新...我需要一些不会过期或可以由后端服务自动刷新的东西。

最好的选择是什么?

Tra*_*cer 6

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

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

Authorization: basic bXktZ29vZC1zZXJ2aWNlOkY2M0JEOTkyLTMzNTUtNDYzNi1CNzFBLTM3RDg0QzI3ODEzRQo=
Run Code Online (Sandbox Code Playgroud)

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

Authorization: bearer eyJhbGciOiJSUzI1NiJ9.ey...
Run Code Online (Sandbox Code Playgroud)

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

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

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

  2. 仅接受 API 中的访问令牌。API 应该只消耗访问令牌。如果 API 接受 ID 令牌,则有 99% 的可能性它会做错事情。

SPA 是您图片中唯一需要 ID 令牌的 SPA。它应该得到它一个访问令牌。此外,它应该从您的OpenID Connect 提供商 (OP) 获取此信息,而不是您客户的提供商。这应该依次将 OpenID 连接到您的客户,但通常会处理身份验证,以便您的应用程序可以在将来处理其他身份验证要求,而无需更改 SPA。此外,其他应用程序可以重用所有这些。

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

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