尝试解码 Jwt 时发生错误:已签名的 JWT 被拒绝:需要另一个算法,或者找不到匹配的密钥
An error occurred while attempting to decode the Jwt: Signed JWT rejected: Another algorithm expected, or no matching key(s) found
我正在尝试使用集成了 spring 安全性的 ForgeRock OpenAM 设置 OAuth2-OpenID 连接,但出现以下错误
2019-06-17 15:01:42.576 DEBUG 62255 --- [nio-8090-exec-2] .o.s.r.w.BearerTokenAuthenticationFilter :
Authentication request for failed: org.springframework.security.oauth2.core.OAuth2AuthenticationException:
An error occurred while attempting to decode the Jwt:
Signed JWT rejected: Another algorithm expected, or no matching key(s) found
Jwk.well-known uri returns支持以下算法:
"id_token_signing_alg_values_supported": [
"PS384",
"ES384",
"RS384",
"HS256",
"HS512",
"ES256",
"RS256",
"HS384",
"ES512",
"PS256",
"PS512",
"RS512"
]
解码后的 JWT 显示如下header:
{
"typ": "JWT",
"zip": "NONE",
"alg": "HS256"
}
有没有一种方法可以根据来自 header 的值设置特定的 JwtDecoder 或强制 AM 使用一种特定的算法?
是的,您可以告诉 AM 使用特定的签名算法进行 OIDC id 令牌签名 (https://backstage.forgerock.com/docs/am/6.5/oidc1-guide/#configure-oauth2-oidc-client-signing),但我怀疑客户端由于缺少密钥而无法验证签名。
只是为了确保...您知道 OAuth2 和 OIDC 是不同的主题..
问题出在访问管理中关于令牌加密的配置。它是空白的,但由于某种原因 JWT header 显示 HS256,导致 spring 寻找 HS256 私钥并失败。在我将设置更改为使用 RS256 后,一切都开始工作了。
在我的例子中,默认情况下 NimbusJwtDecoder
将 RS256
作为 JwsAlgo。所以我配置了 JWTDecoder
并提供了我在 JWT header.
中找到的 RS512
算法
{ "alg": "RS512", "typ": "JWT" }
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
private String jwkSetUri;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().oauth2ResourceServer().jwt().decoder(jwtDecoder());
}
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).jwsAlgorithm(SignatureAlgorithm.RS512).build();
}
}
我正在尝试使用集成了 spring 安全性的 ForgeRock OpenAM 设置 OAuth2-OpenID 连接,但出现以下错误
2019-06-17 15:01:42.576 DEBUG 62255 --- [nio-8090-exec-2] .o.s.r.w.BearerTokenAuthenticationFilter :
Authentication request for failed: org.springframework.security.oauth2.core.OAuth2AuthenticationException:
An error occurred while attempting to decode the Jwt:
Signed JWT rejected: Another algorithm expected, or no matching key(s) found
Jwk.well-known uri returns支持以下算法:
"id_token_signing_alg_values_supported": [
"PS384",
"ES384",
"RS384",
"HS256",
"HS512",
"ES256",
"RS256",
"HS384",
"ES512",
"PS256",
"PS512",
"RS512"
]
解码后的 JWT 显示如下header:
{
"typ": "JWT",
"zip": "NONE",
"alg": "HS256"
}
有没有一种方法可以根据来自 header 的值设置特定的 JwtDecoder 或强制 AM 使用一种特定的算法?
是的,您可以告诉 AM 使用特定的签名算法进行 OIDC id 令牌签名 (https://backstage.forgerock.com/docs/am/6.5/oidc1-guide/#configure-oauth2-oidc-client-signing),但我怀疑客户端由于缺少密钥而无法验证签名。
只是为了确保...您知道 OAuth2 和 OIDC 是不同的主题..
问题出在访问管理中关于令牌加密的配置。它是空白的,但由于某种原因 JWT header 显示 HS256,导致 spring 寻找 HS256 私钥并失败。在我将设置更改为使用 RS256 后,一切都开始工作了。
在我的例子中,默认情况下 NimbusJwtDecoder
将 RS256
作为 JwsAlgo。所以我配置了 JWTDecoder
并提供了我在 JWT header.
RS512
算法
{ "alg": "RS512", "typ": "JWT" }
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
private String jwkSetUri;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().oauth2ResourceServer().jwt().decoder(jwtDecoder());
}
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).jwsAlgorithm(SignatureAlgorithm.RS512).build();
}
}