Message d’erreur
Signed JWT rejected: Invalid signature
Également affiché sous la forme
- 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
Ce que cela signifie
Nimbus a sélectionné une ou plusieurs clés candidates pour le jeton (selon le `kid`, l’`alg` et le type de clé), et aucune d’elles n’a vérifié la signature. La sélection a réussi (sinon vous verriez « Another algorithm expected, or no matching key(s) found ») : les clés auxquelles vous faites confiance et celle qui a signé le jeton sont donc différentes, ou bien le jeton a été modifié. Spring Security signale la même situation via `NimbusJwtDecoder`, avec le préfixe « An error occurred while attempting to decode the Jwt: ».
Pourquoi cela se produit
Même kid, clé différente
fréquenteDes identifiants de clé comme `default`, `rsa1` ou une date sont réutilisés lorsqu’une clé est régénérée (par environnement, par déploiement, après la perte de l’ancienne clé). Le vérificateur trouve une clé portant le bon `kid`, mais qui n’a jamais signé le jeton.
Le serveur de ressources fait confiance aux clés d’un autre émetteur
fréquenteUn `jwk-set-uri` qui pointe vers un autre realm, un autre locataire ou un autre environnement que celui qui émet les jetons.
Le secret HMAC diffère d’un service à l’autre
occasionnelleAvec HS256 et un `MACVerifier`, la moindre différence dans les octets du secret partagé (encodage, saut de ligne final) rend chaque signature invalide.
Le jeton a été modifié après la signature
occasionnelleEn-tête ou charge utile réencodés par un proxy, ou jeton assemblé à partir de morceaux de jetons différents.
Comment corriger l’erreur
- 1.
Configurer l’émetteur, pas un jeu de clés copié à la main
Avec `issuer-uri`, Spring Security lit `jwks_uri` dans le document de découverte de l’émetteur et valide aussi `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.
Comparer les empreintes, pas seulement les valeurs kid
Les empreintes RFC 7638 identifient le matériel de clé lui-même. Si l’empreinte de la clé publiée diffère de celle de la clé avec laquelle l’émetteur signe, le `kid` est réutilisé.
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()); }