JWT(Json 网络令牌)受众 "aud" 与 Client_Id - 有什么区别?

JWT (Json Web Token) Audience "aud" versus Client_Id - What's the difference?

我正在努力在我的身份验证服务器中实施 OAuth 2.0 JWT access_token。但是,我不清楚 JWT aud 声明和 client_id HTTP header 值之间的区别。它们相同吗?如果不是,能否解释一下两者的区别?

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

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

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

this post 简单地说:

The audience of a token is the intended recipient of the token.

The audience value is a string -- typically, the base address of the resource being accessed, such as https://contoso.com.

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

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

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

JWT aud(观众)声明

根据RFC 7519

The "aud" (audience) claim identifies the recipients that the JWT is intended for. Each principal intended to process the JWT MUST identify itself with a value in the audience claim. If the principal processing the claim does not identify itself with a value in the "aud" claim when this claim is present, then the JWT MUST be rejected. In the general case, the "aud" value is an array of case- sensitive strings, each containing a StringOrURI value. In the special case when the JWT has one audience, the "aud" value MAY be a single case-sensitive string containing a StringOrURI value. The interpretation of audience values is generally application specific. Use of this claim is OPTIONAL.

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

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

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

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

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

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

示例:访问与刷新令牌

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

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

中的 refresh 声明来告诉我们令牌是否实际上是有效的刷新令牌

OAuth 客户端 ID 与 JWT aud 声明

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

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

虽然这很老了,但我认为这个问题即使在今天也是有效的

My suspicion is that aud should refer to the resource server(s), and the client_id should refer to one of the client applications recognized by the authentication server

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

In my current case, my resource server is also my web app client.

在OP的场景中,web应用和资源服务器属于同一方。所以这意味着客户和观众是一样的。但也有可能不是这样。

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

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

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

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

OAuth 2.0 访问令牌##

对于 OAuth 2.0 访问令牌,现有答案很好地涵盖了它。此外,这是 OAuth 2.0 Framework (RFC 6749)

中的一个相关部分

For public clients using implicit flows, this specification does not provide any method for the client to determine what client an access token was issued to.
...
Authenticating resource owners to clients is out of scope for this specification. Any specification that uses the authorization process as a form of delegated end-user authentication to the client (e.g., third-party sign-in service) MUST NOT use the implicit flow without additional security mechanisms that would enable the client to determine if the access token was issued for its use (e.g., audience- restricting the access token).

OIDC ID 令牌##

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

aud
REQUIRED. Audience(s) that this ID Token is intended for. It MUST contain the OAuth 2.0 client_id of the Relying Party as an audience value. It MAY also contain identifiers for other audiences. In the general case, the aud value is an array of case sensitive strings. In the common special case when there is one audience, the aud value MAY be a single case sensitive string.

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

azp
OPTIONAL. Authorized party - the party to which the ID Token was issued. If present, it MUST contain the OAuth 2.0 Client ID of this party. This Claim is only needed when the ID Token has a single audience value and that audience is different than the authorized party. It MAY be included even when the authorized party is the same as the sole audience. The azp value is a case sensitive string containing a StringOrURI value.