OAuth 2 将服务器-服务器 API 调用的身份验证与授权分开
Posted
技术标签:
【中文标题】OAuth 2 将服务器-服务器 API 调用的身份验证与授权分开【英文标题】:OAuth 2 separate authentication from authorization for server-server API calls 【发布时间】:2019-01-08 04:35:19 【问题描述】:上下文
我正在尝试为我们公司的产品设计一个具有以下三个属性的访问控制解决方案:
客户可以携带自己的身份(来自他们的 IdP 解决方案),也就是我们可以与他们联合以获得身份。这使他们能够完全控制访问并减轻我们的用户管理工作(目前我们的帮助台的工作量很大!) 我们可以集中控制客户可以使用哪些产品,也就是我们管理授权。这让我们高枕无忧,我们不存在欺诈性使用产品的风险,并集中了目前处于孤立且昂贵的炉管中的操作工作流程。 我们将我们的产品与变幻莫测的单个客户身份协议隔离开来,也就是我们通过某种形式的集线器或网关在客户特定行为和我们的内部产品之间进行转换。这确保了客户可以在所有产品中得到很好的支持,并且只需要与网关团队进行交互,而我们的产品团队也只需要与网关团队和单个协议实现进行交互。我目前的想法是在网关服务中支持 OpenID Connect (OIDC) / OAuth 2 协议,通过销售/运营工作流和信任关系在带外创建客户 IdP 端点和我们的网关之间的信任关系网关和内部产品之间是我们内部开发工作的一部分。
然后消息流变成:
客户从其 IdP 获取身份令牌(由他们决定如何)。 客户向我们的网关服务出示身份令牌,接收产品的访问令牌,假设它们已获得授权。 客户向产品出示访问令牌以获得服务。注意:这是与 Gov.UK 验证身份解决方案类似的设计,不同之处在于它使用 SAML 断言和 IdP 和 RP 的 SAML 联合,以及我们所熟悉的 IdP 之一。
我还期望在后期支持协议/令牌转换(例如:SAML 断言 -> OIDC 令牌),或拥有专有身份提供者机制的客户,并集成我们自己的 IdP (AzureAD) 以供员工访问。
那么问题出在哪里?
似乎 OIDC / OAuth 2 没有现有的流程可以将身份认证和访问授权在两个系统(实际上是安全边界)之间完全分开当没有最终用户时,它不是一部分有用户的设计(所有图表都有一个授权服务器来执行这两项任务)。
我们的大多数客户将从他们的后端调用我们的服务,没有最终用户或浏览器存在,因此我们无法使用支持 id_tokens(或身份验证码)的交互式 OIDC 流程,我们只剩下使用 client_credentials 流,这仅处理访问令牌。
这一切都错了吗(OIDC/OAuth 是不是错误的方法)?
我们是否应该将来自客户的访问令牌转换为网关中的其他访问令牌(因为它们无法创建 id_tokens)?
我知道令牌交换标准草案 (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-token-exchange-14),这有帮助吗?
【问题讨论】:
我现在正在尝试解决同样的问题。你最后做了什么? 查看我的回答@BradC,了解我看到组织在这种情况下使用的一种常见技术。 【参考方案1】:我会考虑JWT 和/或SAML assertion grant types。这些旨在使用由已执行用户身份验证的受信任的第三方身份提供商颁发的令牌从您的 OAuth 服务器获取访问令牌。这将产生一个如下所示的架构:
(4) Look up prod-
ucts +------------+
+----------->+ |
| | API/DB of |
| | products |
+----------------+ +--------------+---+ | |
| Some | | | | |
| Trusted | (3)JWT or SAML grant | Your OAuth | +---+--------+
| IDP <--+ +--------------------->+ server | |
| | | | +----------------+ <------------+
+---+------------+ | | | +--------+------+--+ (5) Allowed products
| | (1) | | (7) Access token ^ |
| OIDC, SAML | | scoped for your APIs | | (6) Burn allowed products into
| or|other | | +<-----+ access token as claims
JWT or SAML | | |
(2) token intended+----+----------+-+ | +------------------+ +----------------+
for your OAuth| +<--+ | | | +<-----+
| server | Some | | | | | |
+----------> Client +------------------->+ Your gateway +------------->+ Your APIs | ^ (11) Fine grained
| | (8) Attempt to | | (10) Attempt| | | authorization using
| | access your APIs | | to access | +------+ claims in access
+-----------------+ with your access +--+-----^---------+ APIs with +----------------+ token
token as proof of | | access token
authentication | | that's been authorized to
+-->--+ an extent
(9) Course grained
authorization using
scope, URL & HTTP method
在第 9 步和第 10 步之间,如果您不使用 split token approach,我可能会将访问令牌转换为 phantom token。这将防止客户端在您的访问令牌中看到只有您自己的内部 API 才需要知道的内容。
【讨论】:
这可能不是主题,但是你用什么工具来制作这个架构?看起来真的很棒。 我用过 asciiflow.com @mababin以上是关于OAuth 2 将服务器-服务器 API 调用的身份验证与授权分开的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ASP.NET MVC 5 和 WEB API 2 中实现 oauth2 服务器 [关闭]
使用服务帐户通过 OAuth 2.0 调用 v3 Google 日历 API 时出现“需要登录”401 未经授权的消息
来自 oauth2 安全休息 Web 服务的 Spring 休息服务 api 调用
通过 OAuth 对 Google API 进行经过身份验证的调用时遇到问题