ChatGPT解决这个技术问题 Extra ChatGPT

JWT(Json Web 令牌)受众“aud”与 Client_Id - 有什么区别?

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

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

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

可能会有所帮助!!实际上,我试图弄清楚 audience 原来是 client_id 也是我的 audience。 (这取决于 keycloak Admin 中的配置。)

Y
Yves M.

事实证明,我的怀疑是正确的。 JWT 中的 Audience aud 声明是指应该接受令牌的资源服务器。

正如 this 帖子所说:

令牌的受众是令牌的预期接收者。受众值是一个字符串——通常是正在访问的资源的基地址,例如 https://contoso.com。

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

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

JWT 将包含一个 aud 声明,该声明指定 JWT 对哪些资源服务器有效。如果 aud 包含 www.myfunwebapp.com,但客户端应用程序尝试使用 www.supersecretwebapp.com 上的 JWT,则访问将被拒绝,因为该资源服务器将看到 JWT 不适合它。


似乎 aud 也可能是 client_id。见tools.ietf.org/id/draft-hunt-oauth-v2-user-a4c-01.txt aud REQUIRED for session_token. Contains the client_id of the client receiving the assertion.
资源服务器不知道客户端将 JWT 发送到何处。资源服务器将如何拒绝从您的 iOS 应用到其他 URL 的此类流量?我不认为你是正确的。
我会说“如果“aud”包含“www.webapp.com”,但客户端应用程序尝试在“secret.webapp.com”上使用 JWT”
RFC 说受众 (aud) 标识收件人。收件人会收到您的 JWT 令牌。如果您有一个网络应用程序,那么这可能是 contoso.com,但如果您有一些桌面或移动应用程序(进行身份验证),则受众没有任何 URI。发行者是生成 JWT 令牌的人,因此很可能是服务器的地址。 RFC 说此声明的使用是可选的,因此仅在需要时使用它。
实际上,我很困惑观众和发行者之间的区别是什么。
C
Community

JWT aud(受众)声明

根据RFC 7519

“aud”(受众)声明标识了 JWT 的目标接收者。打算处理 JWT 的每个主体都必须使用受众声明中的值来标识自己。如果当该声明存在时,处理该声明的主体未使用“aud”声明中的值来标识自己,则必须拒绝 JWT。在一般情况下,“aud”值是区分大小写的字符串数组,每个字符串都包含一个 StringOrURI 值。在 JWT 有一个受众的特殊情况下,“aud”值可能是包含 StringOrURI 值的单个区分大小写的字符串。受众价值的解释通常是特定于应用程序的。使用此声明是可选的。

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

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

当然,接收者可以选择忽略 aud,因此这仅在接收者想要明确验证令牌是专门为其创建时才有用。

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

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

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

示例:访问与刷新令牌

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

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

OAuth 客户端 ID 与 JWT aud 声明

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

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


我对整个“必须识别自己”有点模糊。 RFC7519 充满了类似的无法解释的部分,以及对其他身份验证系统的模糊暗示,这可能是对标准声明字段的正确解释。坦率地说,尽管 RFC 可能很有用,但绝不应该在这种状态下离开草案阶段。
@ChuckAdams 我编辑以澄清我的想法。我同意 RFC 非常模糊,尤其是围绕“标准声明”以及如何/何时使用它们。
我们目前对如何使用 aud 字段进行了相同的讨论,我同意它旨在包含接收者(验证和接受令牌的人)而不是 client_id(要求令牌采取行动的人)代表用户)。
以下内容显然是错误的,并且违反了 RFC 7519:“当然,收件人可能会选择忽略 aud,因此这仅在收件人希望明确验证令牌是专门为其创建的情况下才有用。”来自 RFC 7519 的句子:“如果处理该声明的主体在此声明存在时未使用 aud 声明中的值标识自己,则必须拒绝 JWT。”暗示如果受众声明存在,您必须使用它来检查您是否认同它的价值观之一。
在发行者可以选择不包含它的意义上,它是可选的,但是接收者在它存在时丢弃它不是可选的。
C
Community

如果您来这里搜索 OpenID Connect (OIDC):OAuth 2.0 != OIDC

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

OAuth 2.0 访问令牌##

对于 OAuth 2.0 访问令牌,现有答案很好地涵盖了它。此外,这里是来自 OAuth 2.0 Framework (RFC 6749) 的一个相关部分

对于使用隐式流的公共客户端,本规范没有为客户端提供任何方法来确定向哪个客户端颁发访问令牌。 ... 向客户端验证资源所有者超出了本规范的范围。任何使用授权过程作为委托给客户端的最终用户身份验证形式的规范(例如,第三方登录服务)不得在没有额外的安全机制的情况下使用隐式流程,这些安全机制将使客户端能够确定访问权限颁发令牌供其使用(例如,限制访问令牌的观众)。

OIDC ID 令牌##

除了访问令牌之外,OIDC 还具有 ID 令牌。 OIDC 规范明确说明在 ID 令牌中使用 aud 声明。 (openid-connect-core-1.0)

需要 aud。此 ID 令牌的目标受众。它必须包含依赖方的 OAuth 2.0 client_id 作为受众值。它还可以包含其他受众的标识符。在一般情况下,aud 值是一个区分大小写的字符串数组。在只有一个观众的常见特殊情况下,aud 值可能是一个区分大小写的字符串。

此外,当 aud 具有多个值时,OIDC 指定与 aud 一起使用的 azp 声明。

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


只需要注意一件事:Oauth2 不会强制使用 JWT。
K
Kavindu Dodanduwa

虽然这很旧,但我认为即使在今天也是有效的

我的怀疑是 aud 应该引用资源服务器,而 client_id 应该引用身份验证服务器识别的客户端应用程序之一

是的,aud 应该指代币消费方。其中client_id指代币获取方。

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

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

考虑一个使用 OAuth 受保护资源的 SPA。在这种情况下,SPA 是客户端。受保护的资源是访问令牌的受众。

第二种情况很有趣。 RFC8707“Resource Indicators for OAuth 2.0”解释了您可以在授权请求中使用 resource 参数定义目标受众的位置。因此,生成的令牌将仅限于指定的受众。此外,Azure OIDC 使用类似的方法,它允许资源注册并允许身份验证请求包含资源参数以定义访问令牌目标受众。这种机制允许 OAuth 采用在客户端和令牌消费(观众)方之间进行分离。