Guides JWT

Comment je débogue un JWT audience mismatch

Je compare aud avec l’audience attendue par l’API, vérifie la resource, l’environnement et le type de token, puis corrige la configuration au lieu de désactiver la validation.

Par JWTDecoder.toolsDernière vérification le 2026-09-16

Voix éditoriale : la première personne décrit le workflow documenté de JWTDecoder.tools ; JWTDecoder.tools est l’éditeur et l’auteur organisationnel.

token aud ∋ expected aud
token aud ∋ expected aud

Lorsqu’un JWT se décode correctement, n’est pas expiré et peut même avoir une signature valide, mais que l’API renvoie invalid audience, audience mismatch ou un 401 générique, je traite aud comme une validation distincte. Une signature valide établit l’intégrité et la relation avec une clé de confiance ; elle ne prouve pas que le token est destiné à cette API.

Si je connais déjà l’audience attendue, je commence par JWT Debugger, puis je remonte jusqu’à la manière dont le client a demandé le token.

Ce que aud signifie réellement

RFC 7519 autorise aud sous forme de chaîne ou de tableau :

{ "aud": "api://orders" }
{ "aud": ["api://orders", "api://reporting"] }

L’API doit retrouver son identifiant attendu dans cette valeur. Je n’ajoute pas de normalisation improvisée — minuscules, suppression de slash ou comparaison partielle — sauf si le profil utilisé la définit explicitement.

Je compare d’abord Expected Audience et Actual Audience

API attend : api://orders-prod
Token aud  : api://orders-dev
Résultat   : mismatch

Pour un tableau :

function audienceMatches(aud, expected) {
  if (typeof aud === "string") return aud === expected;
  if (Array.isArray(aud)) return aud.includes(expected);
  return false;
}

expected vient de la configuration de confiance du serveur, jamais du token lui-même.

Cause fréquente : token demandé pour la mauvaise resource

L’authentification peut réussir alors que le client demande un token pour une autre API. Je cherche notamment :

  • scopes d’une autre resource ;
  • identifiant API dev utilisé en prod ;
  • configuration copiée d’un autre environnement ;
  • gateway et backend qui n’attendent pas le même identifiant ;
  • ancien token conservé côté client.

Je corrige l’acquisition OAuth/OIDC, pas la règle de validation.

Cause fréquente : ID Token envoyé à la place de l’Access Token

Un ID Token OpenID Connect est destiné au client qui a lancé l’authentification. Son aud désigne généralement ce client. Une resource API attend plutôt un Access Token destiné à elle.

Si je vois :

{
  "iss": "https://login.example.com/",
  "aud": "web-client-123",
  "sub": "user-42"
}

alors que l’API attend api://orders, je vérifie quelle variable est réellement placée dans Authorization: Bearer.

Cause fréquente : mélange dev/staging/prod

Je lis iss et aud ensemble :

expected iss = https://login.example.com/prod
expected aud = api://orders-prod
actual iss   = https://login.example.com/dev
actual aud   = api://orders-dev

Si les deux pointent vers dev, une erreur d’environnement ou de tenant est plus probable qu’un problème cryptographique.

Messages d’erreur typiques

invalid audience
audience mismatch
token audience is invalid
audience not allowed
unexpected "aud" claim value

Je ne m’arrête pas au texte : je décode aud et le compare à la configuration du serveur.

Pourquoi je ne désactive pas audience validation

Un issuer peut émettre des tokens pour plusieurs APIs. Sans contrôle d’audience, un token prévu pour Service A pourrait être accepté par Service B. RFC 8725 recommande de vérifier cette destination lorsque le profil l’utilise.

Un wildcard n’est donc pas une correction acceptable pour un mauvais paramétrage de resource.

Modifier aud ne répare pas un JWT signé

Changer le payload modifie les octets couverts par la signature. L’ancienne signature doit alors échouer.

Le correctif se trouve généralement dans :

  • resource/audience demandée ;
  • scopes ;
  • audience attendue par l’API ;
  • environnement/tenant ;
  • choix Access Token vs ID Token.

Pour la couche cryptographique, j’utilise JWT Signature Verifier.

Ma matrice de décision

ObservationCause probableAction
aud = client IDID Token utilisé comme Access Tokenvérifier le token envoyé
aud = dev en prodmélange d’environnementscorriger config client/API
aud est un tableaucomparaison incorrectetester l’appartenance
signature valide mais aud fauxmauvaise resourcedemander un nouveau token
iss et aud fauxmauvais tenant/issuervérifier discovery/config

Mon workflow audience mismatch

  1. Je conserve le JWT original sans modification.
  2. Je lis iss, aud, azp, scope et exp avec JWT Decoder.
  3. Je récupère l’Expected Audience dans la configuration de l’API.
  4. Je traite aud correctement comme chaîne ou tableau.
  5. Je confirme qu’un Access Token est envoyé et non un ID Token.
  6. Je compare dev/staging/prod et tenant côté client et serveur.
  7. Je vérifie resource/scope/audience du token request.
  8. Je confirme l’issuer attendu et sa source de clés de confiance.
  9. Je vérifie la signature si nécessaire.
  10. Je corrige acquisition/configuration puis demande un nouveau token.

Si le problème dépasse aud, je poursuis avec le guide JWT 401. Un token authentique n’est pas automatiquement valable pour chaque destinataire.

Sources et références

Guides associés