Fehlermeldung
failed to verify signature: failed to verify id token signature
Auch ausgegeben als
- failed to verify signature: fetching keys oidc: get keys failed
Schlägt schon die Anfrage nach dem JWKS fehl, lautet der Text „failed to verify signature: fetching keys oidc: get keys failed …“, gefolgt vom HTTP- oder Netzwerkfehler.
coreos/go-oidc (Go) — IDTokenVerifier.Verify with a RemoteKeySet
Was der Fehler bedeutet
go-oidc hat den Schlüsselsatz des Providers heruntergeladen (und einmal neu abgerufen, falls der `kid` unbekannt war), und kein veröffentlichter Schlüssel hat die Signatur des Tokens bestätigt. go-oidc unterscheidet nicht zwischen „kein Schlüssel mit diesem kid“ und „ein Schlüssel mit diesem kid, aber falsche Signatur“ – beides heißt, dass das Token nicht mit einem Schlüssel signiert wurde, den dieser Provider aktuell veröffentlicht. Ließ sich der Schlüsselsatz überhaupt nicht abrufen, geht die Meldung stattdessen mit „fetching keys …“ weiter.
Warum der Fehler auftritt
Das Token stammt von einem anderen Provider oder Mandanten
häufigEin Token aus einem Staging-Mandanten, einem anderen Realm oder von einem ganz anderen Identity Provider. Prüfe `iss` in der Payload, bevor du die Schlüssel verdächtigst.
Der Verifier ruft den falschen Schlüsselsatz ab
häufigEine von Hand konfigurierte URL für `NewRemoteKeySet`, die auf die Schlüssel eines anderen Mandanten zeigt, oder ein Proxy oder Cache, der nach einer Rotation ein veraltetes JWKS ausliefert.
Schlüssel-IDs werden für mehrere Schlüssel wiederverwendet
gelegentlichAussteller, die einen `kid` für einen neuen Schlüssel wiederverwenden (etwa einen festen Namen pro Umgebung), erzeugen Tokens, deren `kid` zu einem veröffentlichten Schlüssel passt, der nicht der Signaturschlüssel ist.
Das Token wurde verändert
gelegentlichJede Änderung an Header oder Payload nach dem Signieren – auch eine neue Kodierung – macht die Signatur ungültig.
So behebst du den Fehler
- 1.
Verifier aus der Discovery erzeugen
`provider.Verifier` verwendet die `jwks_uri` aus dem Discovery-Dokument des Providers und dessen Aussteller; damit fallen von Hand konfigurierte URLs als Quelle für Abweichungen weg.
go provider, err := oidc.NewProvider(ctx, "https://accounts.example.com") // discovery gives the right jwks_uri if err != nil { return err } verifier := provider.Verifier(&oidc.Config{ClientID: clientID}) idToken, err := verifier.Verify(ctx, rawIDToken) - 2.
kid des Tokens mit den veröffentlichten Schlüsseln vergleichen
Ist der `kid` nicht veröffentlicht, ist das Token fremd, oder der Provider hat eine Rotation noch nicht abgeschlossen. Ist er veröffentlicht, hat der zugehörige Schlüssel dieses Token nicht signiert.
bash # kid in the token header vs kids the provider publishes python3 -c 'import base64,json,sys; h=sys.argv[1].split(".")[0]; print(json.loads(base64.urlsafe_b64decode(h+"="*(-len(h)%4))))' "$ID_TOKEN" curl -s "$(curl -s https://accounts.example.com/.well-known/openid-configuration | jq -r .jwks_uri)" | jq '.keys[] | {kid, alg, kty}'