Nimbus JOSE + JWT (Java)Java
错误信息
Signed JWT rejected: Another algorithm expected, or no matching key(s) found
也可能输出为
- com.nimbusds.jose.proc.BadJOSEException: Signed JWT rejected: Another algorithm expected, or no matching key(s) found
- org.springframework.security.oauth2.jwt.BadJwtException: An error occurred while attempting to decode the Jwt: Signed JWT rejected: Another algorithm expected, or no matching key(s) found
Nimbus JOSE + JWT (Java) — BadJOSEException from DefaultJWTProcessor; also surfaced by Spring Security's NimbusJwtDecoder
含义
Nimbus 的密钥选择器没有为这个令牌返回任何候选密钥:要么令牌的 `alg` 不在选择器接受的算法之列,要么 JWK 集中没有与令牌的 `kid` 和密钥类型都匹配的密钥。Nimbus 有意不说明是哪一种情况。在 Spring Security 中,这往往是 `NimbusJwtDecoder` 默认的 RS256 遇上了用 ES256 签名的颁发者。
原因
验证方按 RS256 验证
常见Spring Security 的 `NimbusJwtDecoder` 默认使用 RS256,除非你配置了算法(较新的版本也会从颁发者的 JWKS 中发现算法)。Keycloak、Auth0、Azure AD B2C 等都可以用 ES256/PS256 签名。
令牌的 kid 不在 JWK 集中
常见轮换后的密钥尚未发布、JWK 集被缓存,或者 JWK 集 URL 属于另一个颁发者或环境。
密钥元数据把该密钥排除在外
偶见带有 `use: "enc"`、`alg` 不同或密钥类型不同(例如 ES256 令牌遇上 RSA 密钥集)的 JWK 会被匹配器过滤掉。
修复方法
- 1.
告诉解码器颁发者使用的算法
在构建器上调用 `jwsAlgorithm(...)`(或 `jwsAlgorithms(...)`)可以替换默认的 RS256。列表中只保留颁发者实际使用的算法。
java @Bean JwtDecoder jwtDecoder() { return NimbusJwtDecoder.withIssuerLocation("https://issuer.example.com/realms/main") .jwsAlgorithm(SignatureAlgorithm.ES256) // the issuer's algorithm; RS256 is only the default .build(); } - 2.
或者在 application.yml 中配置
Spring Boot 通过 `jws-algorithms` 提供同一设置。
yaml spring: security: oauth2: resourceserver: jwt: issuer-uri: https://issuer.example.com/realms/main jws-algorithms: ES256