ChatGPT解决这个技术问题 Extra ChatGPT

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

I'm working on implementing OAuth 2.0 JWT access_token in my authentication server. But, I'm not clear on what the differences are between the JWT aud claim and the client_id HTTP header value. Are they the same? If not, can you explain the difference between the two?

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 (i.e. web app, or iOS app).

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

Might be helpful!! Actually, I was trying to figure out the audience turns out to be client_id was my audience too. (It depends on the configuration in the keycloak Admin. )

Y
Yves M.

As it turns out, my suspicions were right. The audience aud claim in a JWT is meant to refer to the Resource Servers that should accept the token.

As this post simply puts it:

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.

The client_id in OAuth refers to the client application that will be requesting resources from the Resource Server.

The Client app (e.g. your iOS app) will request a JWT from your Authentication Server. In doing so, it passes it's client_id and client_secret along with any user credentials that may be required. The Authorization Server validates the client using the client_id and client_secret and returns a JWT.

The JWT will contain an aud claim that specifies which Resource Servers the JWT is valid for. If the aud contains www.myfunwebapp.com, but the client app tries to use the JWT on www.supersecretwebapp.com, then access will be denied because that Resource Server will see that the JWT was not meant for it.


It seems that aud may be the client_id too. see 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.
The resource server does not know where the clients sends the JWT. How will the resource server deny such traffic from your iOS-app to some other URL? I don't think you're correct.
I'd say "If the "aud" contains "www.webapp.com", but the client app tries to use the JWT on "secret.webapp.com""
RFC says that audience (aud) identifies the recipients. Recipients receive your JWT tokens. If you have a web app then this probably can be contoso.com but if you have some desktop or mobile app(that authenticates) the audience doesn't have any URI. The issuer is who generates JWT tokens so most probably address of the server. RFC says that usage of this claim is OPTIONAL, so use it only when you need it.
Actually I'm confused what the difference between audience and issuer would be.
C
Community

The JWT aud (Audience) Claim

According to 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.

The Audience (aud) claim as defined by the spec is generic, and is application specific. The intended use is to identify intended recipients of the token. What a recipient means is application specific. An audience value is either a list of strings, or it can be a single string if there is only one aud claim. The creator of the token does not enforce that aud is validated correctly, the responsibility is the recipient's to determine whether the token should be used.

Whatever the value is, when a recipient is validating the JWT and it wishes to validate that the token was intended to be used for its purposes, it MUST determine what value in aud identifies itself, and the token should only validate if the recipient's declared ID is present in the aud claim. It does not matter if this is a URL or some other application specific string. For example, if my system decides to identify itself in aud with the string: api3.app.com, then it should only accept the JWT if the aud claim contains api3.app.com in its list of audience values.

Of course, recipients may choose to disregard aud, so this is only useful if a recipient would like positive validation that the token was created for it specifically.

My interpretation based on the specification is that the aud claim is useful to create purpose-built JWTs that are only valid for certain purposes. For one system, this may mean you would like a token to be valid for some features but not for others. You could issue tokens that are restricted to only a certain "audience", while still using the same keys and validation algorithm.

Since in the typical case a JWT is generated by a trusted service, and used by other trusted systems (systems which do not want to use invalid tokens), these systems simply need to coordinate the values they will be using.

Of course, aud is completely optional and can be ignored if your use case doesn't warrant it. If you don't want to restrict tokens to being used by specific audiences, or none of your systems actually will validate the aud token, then it is useless.

Example: Access vs. Refresh Tokens

One contrived (yet simple) example I can think of is perhaps we want to use JWTs for access and refresh tokens without having to implement separate encryption keys and algorithms, but simply want to ensure that access tokens will not validate as refresh tokens, or vice-versa.

By using aud, we can specify a claim of refresh for refresh tokens and a claim of access for access tokens upon creating these tokens. When a request is made to get a new access token from a refresh token, we need to validate that the refresh token was a genuine refresh token. The aud validation as described above will tell us whether the token was actually a valid refresh token by looking specifically for a claim of refresh in aud.

OAuth Client ID vs. JWT aud Claim

The OAuth Client ID is completely unrelated, and has no direct correlation to JWT aud claims. From the perspective of OAuth, the tokens are opaque objects.

The application which accepts these tokens is responsible for parsing and validating the meaning of these tokens. I don't see much value in specifying OAuth Client ID within a JWT aud claim.


I'm kind of fuzzy on the whole "must identify itself" bit. RFC7519 is full of unexplained bits like that, along with vague allusions to other auth systems, which is likely where the proper interpretation of the standard claims fields is to be found. Frankly the RFC, useful as it may be, should never have left draft stage in such a state.
@ChuckAdams I edited to clarify my thoughts. I agree the RFC is very vague especially around the "standard claims" and how/when to use them.
We currently have the same discussion on how to use the aud-field and I agree that it's meant to contain the recipient (the one who validates and accepts the token) and not the client_id (the one, who asked for the token to act on behalf of the user).
The following is just plainly wrong and goes against RFC 7519: "Of course, recipients may choose to disregard aud, so this is only useful if a recipient would like positive validation that the token was created for it specifically." The senctence from RFC 7519: "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." Implies that if the audience claim is present, that you must use it to check if you identify with one of its values.
It is optional in the sense that the issuer may choose not include it, however it is not optional for the recipient to discard it when it is present.
C
Community

If you came here searching OpenID Connect (OIDC): OAuth 2.0 != OIDC

I recognize that this is tagged for oauth 2.0 and NOT OIDC, however there is frequently a conflation between the 2 standards since both standards can use JWTs and the aud claim. And one (OIDC) is basically an extension of the other (OAUTH 2.0). (I stumbled across this question looking for OIDC myself.)

OAuth 2.0 Access Tokens##

For OAuth 2.0 Access tokens, existing answers pretty well cover it. Additionally here is one relevant section from 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 Tokens##

OIDC has ID Tokens in addition to Access tokens. The OIDC spec is explicit on the use of the aud claim in ID Tokens. (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.

furthermore OIDC specifies the azp claim that is used in conjunction with aud when aud has more than one value.

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.


Just to note one thing: Oauth2 doesn't force use of JWT.
K
Kavindu Dodanduwa

Though this is old, I think question is valid even today

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

Yes, aud should refer to token consuming party. And client_id refers to token obtaining party.

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

In the OP's scenario, web app and resource server both belongs to same party. So this means client and audience to be same. But there can be situations where this is not the case.

Think about a SPA which consume an OAuth protected resource. In this scenario SPA is the client. Protected resource is the audience of access token.

This second scenario is interesting. RFC8707 "Resource Indicators for OAuth 2.0" explains where you can define the intended audience in your authorization request using resource parameter. So the resulting token will restricted to the specified audience. Also, Azure OIDC use a similar approach where it allows resource registration and allow auth request to contain resource parameter to define access token intended audience. Such mechanisms allow OAuth adpotations to have a separation between client and token consuming (audience) party.