JWT (Json Web 令牌)用户“ aud”与 Client _ Id-有什么区别?

我正在我的身份验证服务器中实现 OAuth 2.0 JWT access _ token。但是,我不清楚 JWT aud声明和 client_id HTTP 头值之间的区别。他们是一样的吗?如果没有,你能解释一下这两者之间的区别吗?

我怀疑 aud应该指的是资源服务器,而 client_id应该指的是认证服务器(即 Web 应用程序或 iOS 应用程序)识别的客户端应用程序之一。

在我目前的情况下,我的资源服务器也是我的 Web 应用程序客户端。

196441 次浏览

事实证明,我的怀疑是对的。JWT 中的受众 aud声明意味着引用应该接受令牌的资源服务器。

正如 这个的文章所言:

令牌的受众是预期的令牌接收者。

受众值是一个字符串——通常是 被访问的资源,例如 https://contoso.com

OAuth 中的 client_id引用将从资源服务器请求资源的客户机应用程序。

客户端应用程序(例如 iOS 应用程序)将从验证服务器请求 JWT。在这样做时,它将传递它的 client_idclient_secret以及可能需要的任何用户凭据。AuthorizationServer 使用 client_idclient_secret验证客户端,并返回一个 JWT。

JWT 将包含一个 aud声明,指定 JWT 适用于哪些资源服务器。如果 aud包含 www.myfunwebapp.com,但是客户端应用程序试图在 www.supersecretwebapp.com上使用 JWT,那么访问将被拒绝,因为资源服务器将看到 JWT 并不适合它。

JWT aud(受众)索赔

根据 RFC 7519:

“ aud”(受众)声明标识 JWT 是哪些收件人 每个用于处理 JWT 的主体必须 与受众声明中的一个值一致。如果主体 处理索赔时,不会使用 如果存在此索赔,则 JWT 必须是“ aud”索赔 在一般情况下,“ aud”值是大小写-的数组 敏感字符串,每个字符串包含一个 StringOrURI 值 特殊情况下,当 JWT 只有一个用户时,“ aud”值可能是 包含 StringOrURI 值的区分大小写的单个字符串 对受众价值观的诠释一般是应用特定的。 使用此索赔是可选的。

规范定义的受众(aud)声明是通用的,并且是特定于应用程序的。预期的用途是标识令牌的预期收件人。收件人的意思是特定于应用程序的。观众值可以是字符串列表,也可以是单个字符串(如果只有一个 aud声明)。令牌的创建者不强制正确验证 aud,而是由接收者决定是否应该使用令牌。

无论值是什么,当收件人正在验证 JWT 并希望验证令牌是否用于其目的时,它必须确定 aud中的哪个值标识自己,令牌只有在 aud声明中存在收件人声明的 ID 时才进行验证。这是一个 URL 还是其他应用程序特定的字符串并不重要。例如,如果我的系统决定在 aud中用字符串 api3.app.com标识自己,那么只有当 aud声明在其受众值列表中包含 api3.app.com时,它才应该接受 JWT。

当然,收件人可能会选择忽略 aud,因此只有在收件人希望确认该令牌是专门为其创建的时候,这才有用。

我基于规范的解释是,aud声明对于创建专门构建的 JWT 是有用的,这些 JWT 只有在特定的目的下才有效。对于一个系统,这可能意味着您希望令牌对某些特性有效,但对其他特性无效。您可以发出仅限于某个“受众”的令牌,同时仍然使用相同的密钥和验证算法。

因为在典型的情况下,JWT 是由受信任的服务生成的,并由其他受信任的系统(不希望使用无效令牌的系统)使用,所以这些系统只需要协调它们将要使用的值。

当然,aud是完全可选的,如果您的用例不需要它,可以忽略它。如果您不想将令牌限制为由特定的受众使用,或者您的系统实际上都不会验证 aud令牌,那么它就是无用的。

示例: 访问与刷新令牌

我能想到的一个人为(但简单)的例子是,我们可能希望使用 JWT 进行访问和刷新令牌,而不必实现单独的加密密钥和算法,但只是希望确保访问令牌不会作为刷新令牌进行验证,反之亦然。

通过使用 aud,我们可以在创建这些令牌时指定刷新令牌的 refresh声明和访问令牌的 access声明。当请求从刷新令牌获取新的访问令牌时,我们需要验证该刷新令牌是否为真正的刷新令牌。上面描述的 aud验证将通过在 aud中专门查找 refresh的声明来告诉我们这个令牌是否实际上是一个有效的刷新令牌。

OAuth 客户端 ID 与 JWT aud索赔

OAuth 客户端 ID 是完全不相关的,与 JWT aud索赔没有直接关联。从 OAuth 的角度来看,令牌是不透明的对象。

接受这些令牌的应用程序负责解析和验证这些令牌的含义。在 JWT aud声明中指定 OAuth Client ID 没有多大价值。

虽然这是旧的,我认为问题是有效的,即使在今天

我怀疑 aud 应该引用资源服务器,并且 Client _ id 应该引用一个客户机应用程序 由身份验证服务器识别

是的,Aud应该指令牌消费方,而 Client _ id指令牌获取方。

在我目前的情况下,我的资源服务器也是我的 Web 应用程序客户端。

在 OP 的场景中,Web 应用程序和资源服务器都属于同一方。这意味着客户和观众是一样的。但在某些情况下,情况可能并非如此。

考虑一个使用 OAuth 保护资源的 SPA。在这个场景中,SPA 是客户机。受保护的资源是访问令牌的受众。

第二个场景很有趣。RFC8707“ OAuth 2.0的资源指标”解释了在哪里可以使用 资源参数在授权请求中定义预期的受众。因此,结果令牌将仅限于指定的受众。此外,Azure OIDC 使用类似的方法,允许资源注册,允许认证请求包含资源参数,以定义访问令牌预期的受众。这种机制允许 OAuth 适配在客户端和令牌消费(受众)方之间进行分离。

如果你来这里搜索 OpenID 连接(OIDC) : OAuth 2.0! = OIDC

我知道这是为 oauth 2.0和 没有 OIDC 标记的,但是这两个标准之间经常混淆,因为两个标准 可以都使用 JWT 和 aud声明。一个(OIDC)基本上是另一个(OAUTH 2.0)的扩展。(我偶然发现了这个问题,正在寻找 OIDC。)

OAuth 2.0 Access Token # #

对于 OAuth 2.0 访问令牌,现有的答案已经很好地涵盖了它

对于使用隐式流的公共客户端,此规范不会 为客户端提供任何方法来确定访问哪个客户端 发给。
...
对客户端进行资源所有者身份验证超出了此范围 任何使用授权过程的规范 作为委托给客户端的最终用户认证形式(例如, 第三方登录服务)必须使用隐式流 额外的安全机制,使客户端能够 确定接达标记是否为使用而发出(例如: 限制访问令牌)。

OIDC ID 令牌 # #

OIDC 除了访问令牌之外还有 身份证件。OIDC 规范明确规定了在 ID 令牌中使用 aud声明。(Openid-connect-core-1.0)

奥德
需要。此 ID 令牌适用于。它还可能包含其他受众的标识符。在一般情况下,aud 值是区分大小写的字符串数组。在通常的特殊情况下,只有一个读取对象时,aud 值可能是一个区分大小写的字符串。

此外,OIDC 指定了当 aud具有一个以上值时与 aud一起使用的 azp索赔。

Azp
可以选择。授权方-向其发放 ID 令牌的方。如果存在,它必须包含该方的 OAuth 2.0客户端 ID。只有当 ID 令牌具有单个受众值且该受众与授权方不同时,才需要此声明。即使授权方与唯一的受众相同,它也可以包括在内。Azp 值是一个区分大小写的字符串,包含一个 StringOrURI 值。