Fehlermeldung
Signed JWT rejected: Invalid signature
Auch ausgegeben als
- com.nimbusds.jose.proc.BadJWSException: Signed JWT rejected: Invalid signature
- org.springframework.security.oauth2.jwt.BadJwtException: An error occurred while attempting to decode the Jwt: Signed JWT rejected: Invalid signature
Nimbus JOSE + JWT (Java) — BadJWSException from DefaultJWTProcessor; also surfaced by Spring Security's NimbusJwtDecoder
Was der Fehler bedeutet
Nimbus hat für das Token einen oder mehrere Kandidatenschlüssel ausgewählt (nach `kid`, `alg` und Schlüsseltyp), aber mit keinem davon ließ sich die Signatur prüfen. Die Auswahl war erfolgreich – sonst würdest du „Another algorithm expected, or no matching key(s) found“ sehen –, also unterscheiden sich die Schlüssel, denen du vertraust, von dem Schlüssel, der das Token signiert hat, oder das Token wurde verändert. Spring Security meldet denselben Zustand über `NimbusJwtDecoder` mit dem Präfix „An error occurred while attempting to decode the Jwt:“.
Warum der Fehler auftritt
Gleicher kid, anderer Schlüssel
häufigSchlüssel-IDs wie `default`, `rsa1` oder ein Datum werden wiederverwendet, wenn ein Schlüssel neu erzeugt wird (pro Umgebung, pro Deployment, nach dem Verlust des alten Schlüssels). Der Verifizierer findet einen Schlüssel mit dem richtigen `kid`, der das Token nie signiert hat.
Der Ressourcenserver vertraut den Schlüsseln eines anderen Ausstellers
häufigEine `jwk-set-uri`, die zu einem anderen Realm, Mandanten oder einer anderen Umgebung gehört als die Tokens.
Das HMAC-Secret unterscheidet sich zwischen den Diensten
gelegentlichMit HS256 und einem `MACVerifier` macht jede Abweichung in den Bytes des Shared Secrets (Kodierung, abschließender Zeilenumbruch) jede Signatur ungültig.
Das Token wurde nach dem Signieren verändert
gelegentlichHeader oder Payload wurden von einem Proxy neu kodiert, oder ein Token wurde aus Teilen verschiedener Tokens zusammengesetzt.
So behebst du den Fehler
- 1.
Aussteller konfigurieren, keinen von Hand kopierten Schlüsselsatz
Mit `issuer-uri` liest Spring Security `jwks_uri` aus dem Discovery-Dokument des Ausstellers und prüft zusätzlich `iss`.
yaml # Spring Boot resource server: derive the JWK Set from the issuer's discovery document spring: security: oauth2: resourceserver: jwt: issuer-uri: https://issuer.example.com/realms/main - 2.
Thumbprints vergleichen, nicht nur kids
Thumbprints nach RFC 7638 identifizieren das tatsächliche Schlüsselmaterial. Unterscheidet sich der Thumbprint des veröffentlichten Schlüssels von dem des Schlüssels, mit dem der Aussteller signiert, wird der `kid` wiederverwendet.
java SignedJWT jwt = SignedJWT.parse(token); System.out.println(jwt.getHeader().getKeyID() + " " + jwt.getHeader().getAlgorithm()); JWKSet set = JWKSet.load(new java.net.URI("https://issuer.example.com/.well-known/jwks.json").toURL()); for (JWK key : set.getKeys()) { System.out.println(key.getKeyID() + " " + key.getAlgorithm() + " thumbprint=" + key.computeThumbprint()); }