SPA + API + OIDC:仅提供 ACCESS 令牌时如何验证 API 调用者?

Posted

技术标签:

【中文标题】SPA + API + OIDC:仅提供 ACCESS 令牌时如何验证 API 调用者?【英文标题】:SPA + API + OIDC: How to authenticate an API caller when it's only providing an ACCESS token? 【发布时间】:2019-03-28 00:21:41 【问题描述】:

假设您正在开发一个客户端 javascript SPA 应用程序 (Angular)、该应用程序的后端 API(在我的例子中为 ASP.NET Core),并且您使用实现 Open ID Connect 协议的身份提供程序(我正在使用身份服务器4)。

显然,保护应用的推荐方法是在 JavaScript 应用和身份提供者之间使用 OIDC 隐式流,如果成功,JavaScript 应用会获得一个 id 令牌和一个访问令牌。 p>

现在根据this documentation,JavaScript 应用程序应该在调用 API 时在标头中传递 访问令牌。而且我不确定 id 令牌 在这种情况下有什么用途(除了在您的 JavaScript 应用程序中自定义 UI)?

但这是令人困惑的部分:文档还说您永远不应该使用访问令牌进行身份验证。但这是我的 API 在请求标头中收到的令牌,那么它如何验证用户身份呢?如果我的 API 接收到Post(newRecord),并且 API 需要在内部修复newRecord 上的一些审计信息(即newRecord.CreatedBy = CurrentUsername),它如何在不验证调用者的情况下做到这一点?

我想我漏掉了一块拼图。非常感谢任何帮助。

【问题讨论】:

【参考方案1】:

简答/建议

使用访问令牌访问 API 端点。从 API 端点,您必须使用token introspection 端点来验证令牌有效性(活动状态)以及获取在授权服务器上进行身份验证的主体。 IdentityServer 对此提供支持。文档可从here 获得。

说明

ID 令牌旨在供接收客户端使用。它将允许您的客户端对最终用户进行身份验证并提供用户特定的定制。这就是 OpenID Connect (OIDC) 的全部目的。另一方面OAuth 2.0 提供了一个授权框架。它将用户凭证替换为访问令牌,从而提高 API 访问安全性(与基本身份验证和随处存储用户凭证相比)。因此 OIDC 建立在 OAuth 2.0 之上,您可以通过 OIDC 流程获得 ID 令牌和访问令牌。

但正如您已经知道(并且之前提到的),ID 令牌是为客户设计的。可能存在 ID 令牌在客户端和服务器之间传递的特殊情况。这主要是当两者都由同一方控制时。但是访问令牌是正确访问 API 端点的关键。

访问令牌可以是不透明的字符串或 JWT。当它是 JWT 时,API 可以读取和理解令牌(自包含)。当它不透明时,在 API 端点验证令牌的唯一方法是使用令牌自省端点。如果 API 可以验证令牌的有效性,那么它可以授予访问(授权)请求。此外,如果用户详细信息(主题)可用(通过 JWT 或作为自省响应),则可以执行特定于用户的检查。这进一步扩展到令牌范围值。但归根结底,您是在授权 API 请求,而不是在 API 端点对用户进行身份验证。这就是亮点。希望现在一切都清楚了!

【讨论】:

假设 SPA 从身份提供者那里接收到 Id 令牌和访问令牌。然后 SPA 完成了任务并验证了 id 令牌的签名。现在,如果用户是恶意的,他/她可以使用 SPA 保留的这些令牌做任何事情(因为它是 SPA 并且本质上是开放的)。所以用户可以随意用其他任何东西替换访问令牌。因此,当 API 从 SPA 接收访问令牌并使用其中的声明来确保这是 Joe 时,它​​似乎依赖于访问令牌进行身份验证 这就是为什么我这辈子都不明白为什么身份提供者首先要发送两个令牌,这似乎毫无意义。以及为什么他们在文档中强调访问令牌不适用于身份验证 对于会话也可以这样说。想想一个简单的网络应用程序依赖于一个会话。如果他/她真的想要,最终用户可以使用这些值来做任何事情。但是从服务提供商的角度来看,会话可以从第三方获得。由于协议的设计方式,存在两个令牌。 OIDC 基于 OAuth 2.0 构建。因此,OIDC 具有用于客户端应用程序身份验证的 ID 令牌和用于受保护资源访问的访问令牌。 ID 令牌不打算共享 除了这个讨论过时,最近 OAuth 工作组决定不推荐隐式流 - medium.com/@torsten_lodderstedt/… 。这证明了你的一些怀疑。

以上是关于SPA + API + OIDC:仅提供 ACCESS 令牌时如何验证 API 调用者?的主要内容,如果未能解决你的问题,请参考以下文章

从 ASP.NET Core MVC 项目提供 Angular SPA 时,我可以使用 OIDC 混合流吗?

是否有基于 OIDC 的基于 IDaaS 的社交登录的标准模式?

使用 .Net 5 WebAPI 的 Vue SPA 的正确 OIDC 流程是啥?

从 Keycloak 访问 admin/groups OIDC API 时出现错误 403

ID4 ADFS 3.0 和 oidc-client (vue spa) - 回调实现

为啥 quarkus.oidc.credentials.secret 被忽略?