JWT-Guides

So debugge ich einen JWT Audience Mismatch

Ich vergleiche aud mit der erwarteten API Audience, prüfe falsche Ressourcen, Environment-Mixups und Token-Typen und korrigiere die eigentliche Konfiguration statt die Prüfung abzuschalten.

Von JWTDecoder.toolsZuletzt geprüft 2026-09-16

Redaktionelle Stimme: Formulierungen in der ersten Person beschreiben den dokumentierten Workflow von JWTDecoder.tools; Herausgeber und Organisationsautor ist JWTDecoder.tools.

token aud ∋ expected aud
token aud ∋ expected aud

Wenn ein JWT sauber dekodiert, nicht abgelaufen und sogar korrekt signiert ist, die API es aber mit invalid audience, audience mismatch oder einem generischen 401 ablehnt, behandle ich aud als eigenen Validierungsschritt. Ein gültiger Signaturnachweis beantwortet nur, wer das Token signiert hat und ob die Bytes unverändert sind. aud beantwortet, für welchen Empfänger das Token gedacht ist.

Wenn ich Expected Audience und Token bereits kenne, beginne ich mit dem JWT Debugger und prüfe danach die Token-Beschaffung im Client.

Was aud tatsächlich aussagt

RFC 7519 erlaubt aud als einzelnen String oder als Array von Strings:

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

Die prüfende API sollte nur akzeptieren, wenn ihre konfigurierte erwartete Audience im Claim enthalten ist. Ich vergleiche dabei die tatsächlichen Identifier und erfinde keine Normalisierung wie lowercasing, automatisches Entfernen von Slashes oder Teilstring-Matches, wenn das verwendete Profil das nicht ausdrücklich vorsieht.

Mein erster Vergleich: Expected gegen Actual

Ich schreibe beide Werte nebeneinander. Das verhindert, dass ich mich in Decoder-Ausgaben verliere:

API erwartet: api://orders-prod
Token aud:    api://orders-dev
Ergebnis:     mismatch

Ist aud ein Array, prüfe ich Membership statt String-Gleichheit:

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

Diese Funktion ist nur die Vergleichslogik. Die Anwendung muss expected aus vertrauenswürdiger Konfiguration beziehen, nicht aus dem Token.

Häufige Ursache 1: Der Client fordert ein Token für die falsche Resource an

Bei OAuth/OIDC kann der Login erfolgreich sein und trotzdem ein Token für den falschen Empfänger entstehen. Typische Hinweise sind:

  • die aufgerufene API ist orders, aud zeigt aber auf billing;
  • der Client fordert Scopes einer anderen API an;
  • Dev- und Prod-Konfiguration wurden gemischt;
  • ein API-Gateway erwartet einen Resource-Identifier, der Client verwendet aber eine Client-ID;
  • die Token-Beschaffung wurde kopiert, ohne die Ziel-Resource anzupassen.

Ich korrigiere dann die Authorization-/Token-Request-Konfiguration. Ich mache die API nicht permissiver und editiere das JWT nicht.

Häufige Ursache 2: ID Token wird als Access Token an die API gesendet

Ein OpenID-Connect-ID-Token ist primär für den Client bestimmt. Seine aud enthält typischerweise den Client, der die Anmeldung angefordert hat. Eine Resource API erwartet dagegen ein Access Token, dessen Audience zur API passt.

Wenn ich so etwas sehe:

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

während die API api://orders erwartet, prüfe ich zuerst, ob im Authorization: Bearer-Header versehentlich das ID Token steckt.

Häufige Ursache 3: Dev, Staging und Prod sind vermischt

Audience und Issuer prüfe ich zusammen:

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

Wenn beide Werte auf Dev zeigen, ist ein Environment-Mixup wesentlich wahrscheinlicher als ein Kryptografieproblem. Dann kontrolliere ich Client-Konfiguration, Secrets, Redirect-Ziele, Discovery URL und die API-Environment-Variablen.

Welche Fehlermeldungen ich dem aud-Problem zuordne

Frameworks formulieren unterschiedlich. Ich suche nach Varianten wie:

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

Ich verlasse mich trotzdem nicht auf den Wortlaut allein. Ich dekodiere den Claim und vergleiche ihn mit der Serverkonfiguration.

Warum ich Audience Validation nicht abschalte

Ein Issuer kann Tokens für mehrere APIs oder Clients ausstellen. Ohne Audience-Prüfung besteht das Risiko, dass ein für Service A ausgestelltes Token bei Service B akzeptiert wird. RFC 8725 empfiehlt deshalb, die Zielgruppe im jeweiligen Einsatzprofil explizit zu prüfen.

Das Abschalten der Prüfung ist keine Lösung für eine falsch konfigurierte Resource. Es verschiebt den Fehler vom Deployment in die Vertrauensgrenze.

aud editieren repariert kein signiertes Token

Wenn ich aud von api://billing auf api://orders ändere, ändern sich die signierten Payload-Bytes. Die ursprüngliche Signatur darf danach nicht mehr gültig sein.

Der richtige Fix liegt an einem dieser Orte:

  • Token Request / Resource / Scope;
  • API Expected Audience;
  • Environment-Konfiguration;
  • Token-Typ-Auswahl;
  • Issuer-/Tenant-Konfiguration.

Für Signaturfragen nutze ich den JWT Signature Verifier, nicht einen Payload-Editor.

Meine Entscheidungsmatrix

BeobachtungWahrscheinlichste UrsacheNächster Schritt
aud = Client-IDID Token statt Access TokenToken-Variable und OAuth Flow prüfen
aud = Dev, API = ProdEnvironment-MixupClient/API-Konfiguration angleichen
aud ist Arrayfalsche VergleichslogikMembership statt String-Vergleich
Signatur gültig, aud falschfalsche ResourceToken neu für richtige API anfordern
iss und aud beide falschfalscher Tenant/IssuerDiscovery- und Issuer-Konfiguration prüfen

Mein Audience-Mismatch-Workflow

  1. Ich bewahre das originale JWT unverändert auf.
  2. Ich dekodiere iss, aud, azp, scope und exp mit dem JWT Decoder.
  3. Ich lese die Expected Audience aus der API-Konfiguration.
  4. Ich behandle aud korrekt als String oder Array.
  5. Ich prüfe, ob Access Token und ID Token verwechselt wurden.
  6. Ich vergleiche Dev/Staging/Prod und Tenant auf Client- und API-Seite.
  7. Ich prüfe Resource/Scope/Audience im Token Request.
  8. Ich bestätige den erwarteten iss und dessen vertrauenswürdige Schlüsselquelle.
  9. Ich verifiziere die Signatur, falls das noch nicht geschehen ist.
  10. Ich ändere die fehlerhafte Acquisition-/Server-Konfiguration und fordere ein neues Token an.

Wenn der Fehler breiter als aud ist, gehe ich mit der JWT-401-Anleitung durch die komplette Authentifizierungskette. Die Kernregel bleibt: Ein authentisches Token ist nicht automatisch für jede API bestimmt.

Quellen und Referenzen

Verwandte Guides