Перейти к содержимому
ecdsa.com
Nimbus JOSE + JWT (Java)Java

Сообщение об ошибке

Signed JWT rejected: Invalid signature

Также выводится как

  • 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

Что это означает

Nimbus выбрал для токена один или несколько ключей-кандидатов (по `kid`, `alg` и типу ключа), но ни один из них не подтвердил подпись. Выбор прошёл успешно (иначе вы увидели бы «Another algorithm expected, or no matching key(s) found»), значит, ключи, которым вы доверяете, и ключ, которым подписан токен, разные, либо токен изменили. Spring Security сообщает о той же ситуации через `NimbusJwtDecoder` с префиксом «An error occurred while attempting to decode the Jwt:».

Почему это происходит

Как исправить

  1. 1.

    Укажите издателя, а не скопированный вручную набор ключей

    С `issuer-uri` Spring Security берёт `jwks_uri` из документа обнаружения издателя и заодно проверяет `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. 2.

    Сравнивайте отпечатки, а не только kid

    Отпечатки по RFC 7638 идентифицируют сам ключевой материал. Если отпечаток опубликованного ключа отличается от отпечатка ключа, которым подписывает издатель, значит, `kid` используется повторно.

    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());
    }

Связанные ошибки

Открыть всю базу ошибок подписей