You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security 6中使用client_secret_jwt获取OAuth2令牌失败求助

Spring Security 6 client_secret_jwt 认证失败问题解决

核心问题:签名算法不匹配

从异常信息 Signed JWT rejected: Another algorithm expected, or no matching key(s) found 可以明确,你的客户端配置与JWT生成代码使用了不同的签名算法:

  • 客户端注册时指定了 RS256(非对称RSA算法)
  • 但生成JWT时用了 HS256(对称HMAC算法)

这是导致认证失败的根本原因,以下是两种修复方案:


方案一:使用对称加密(HS256)

这种方式更简单,适合快速验证:

1. 修改客户端注册配置

将签名算法改为 HS256,并移除JWKS配置(HS算法无需公钥集):

@Bean
public RegisteredClientRepository registeredClientRepository() {
    RegisteredClient registeredClient =
            RegisteredClient
                    .withId(UUID.randomUUID().toString())
                    .clientId("client")
                    .clientSecret("secret_secret_secret_secret_secret")
                    .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_JWT)
                    .clientSettings(ClientSettings.builder()
                            // 改为HS256对称算法
                            .tokenEndpointAuthenticationSigningAlgorithm(SignatureAlgorithm.HS256)
                            // 移除jwkSetUrl配置
                            .build())
                    .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
                    .redirectUri("https://www.manning.com/authorized")
                    .scope("CUSTOM")
                    .build();

    return new InMemoryRegisteredClientRepository(registeredClient);
}

2. 保留现有JWT生成代码

你的getJWTToken方法已经使用了HS256签名,且密钥与客户端clientSecret一致,无需修改。


方案二:使用非对称加密(RS256)

如果需要更安全的非对称认证,按以下步骤调整:

1. 生成RSA密钥对

添加密钥生成逻辑:

private static RSAKey generateRsaKey() {
    try {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        return new RSAKey.Builder(publicKey)
                .privateKey(privateKey)
                .keyID(UUID.randomUUID().toString())
                .build();
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}

private final RSAKey rsaKey = generateRsaKey();

2. 修改JWT生成代码

使用RSA私钥签名:

private String getJWTToken(String username) {
    String token = Jwts.builder()
            .subject(username)
            .issuer(username)
            .id(UUID.randomUUID().toString())
            .audience().add("http://localhost:8080/oauth2/token").and()
            .issuedAt(new Date(System.currentTimeMillis()))
            .expiration(new Date(System.currentTimeMillis() + 600*1000))
            // 使用RSA私钥和RS256算法签名
            .signWith(rsaKey.toPrivateKey(), SignatureAlgorithm.RS256)
            .compact();
    return token;
}

3. 保留客户端注册配置

你的现有RegisteredClient配置已经指定了RS256和JWKS地址,无需修改(Spring Security会自动暴露/oauth2/jwks端点)。


验证请求

确保你的curl请求参数正确:

curl -X POST -v \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=生成的JWT令牌" \
  http://localhost:8080/oauth2/token

内容的提问来源于stack exchange,提问作者Vaibhav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 13:15:02