资源服务器应如何验证授权服务器颁发的 oauth 不记名令牌?

Posted

技术标签:

【中文标题】资源服务器应如何验证授权服务器颁发的 oauth 不记名令牌?【英文标题】:How resource server should validate oauth bearer token that issued by Authorization Server? 【发布时间】:2020-11-25 20:54:19 【问题描述】:

假设我有一个授权服务器 (AS),它应该产生 access_token,并且我有另一个资源服务器 (RS),它为我的受保护资源提供服务。

我想知道RS应该如何验证AS产生的access_token

我的困惑是,AS 在签名access_token 时应该有它的秘密方式,这并不意味着其他任何人都不会共享或知道,在这种情况下,RS 不应该知道 AS 是如何生成这个access_token .

在这种情况下,RS 应该如何验证接收到的令牌并确保令牌来自已识别的 AS?相反,验证 RS 上收到的令牌不应该是 AS 的责任吗?但如果是这样的话,它不会面临任何性能瓶颈,因为对 RS 的每个 API 调用都需要额外的跳转到 AS 来验证令牌?

【问题讨论】:

【参考方案1】:

通常由 AS 发行的令牌使用私钥进行签名。 AS 还发布任何人都可以下载的公钥。例如,谷歌发布了它的公共签名密钥here。

RS收到access-token后,从AS下载公钥,验证token的签名。如果匹配其接受。除了验证签名之外,它还会检查令牌中的其他声明,例如 aud-claim(受众),如果他的令牌实际上是供 RS 使用的。

或者,RS 可以使用共享密钥来验证令牌。在这种情况下,RS 是一个受信任的(机密客户端),我们知道它可以保守秘密,并且可以安全地与我们信任的服务共享秘密。

【讨论】:

【参考方案2】:

正如您所说的 Isaac,有些人(包括我自己)更喜欢将令牌验证从 API 外部化,并要求授权服务器来完成这项工作。我认为这是最干净的选择,因为:

它将所有 API 的安全代码外部化 可以在不影响 API 的情况下更改令牌签名密钥或算法

这可以通过introspection 实现,这通常还涉及缓存结果(声明)。这就是很多 API 网关解决方案的工作原理,但您也可以很容易地自己编写代码。

我的一些相关资源:

API Authorization Blog Post Introspection Code

Tore 描述的技术也是完全有效的,如果授权服务器不支持自省,则需要此技术。

【讨论】:

以上是关于资源服务器应如何验证授权服务器颁发的 oauth 不记名令牌?的主要内容,如果未能解决你的问题,请参考以下文章

配置多个 OAuth2 授权服务器和单个资源服务器之间的通信

Spring OAuth:带有授权服务器后端的资源服务器

OAuth 2.0 的四种授权模式

OAuth 2.0系列--- 授权服务器

Spring security oauth2 在 30 秒后未能通过颁发者验证

OAuth2介绍