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

将Spring Authorization Server作为Keycloak IDP时JWK验证失败问题

Spring Authorization Server作为Keycloak IDP时签名验证失败问题排查与解决

问题描述

基于Spring Authorization Server官方示例搭建OAuth2授权服务器,将其配置为Keycloak的身份提供商(IDP)后,Keycloak可正常重定向到Spring授权服务器的登录页面,但登录完成后抛出签名验证失败异常:

2024-08-07 17:57:36,179 WARN  [org.keycloak.keys.infinispan.InfinispanPublicKeyStorageProvider] (executor-thread-11) PublicKey wasn't found in the storage. Requested kid: 'd2ff780e-5b42-4f7a-83dc-e7bd23d838de' . Available kids: '[]'
2024-08-07 17:57:36,180 ERROR [org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider] (executor-thread-11) Failed to make identity provider oauth callback: org.keycloak.broker.provider.IdentityBrokerException: token signature validation failed

直接访问Spring授权服务器的JWK URI,能看到Keycloak请求的kid对应的密钥,且通过授权码模式直接对接Spring授权服务器生成的JWT,签名和头在本地验证完全正常。

解决方向

1. 确认Keycloak对JWK端点的访问有效性

  • 检查Keycloak IDP的OpenID Connect配置中,JWKS URL是否准确指向Spring Authorization Server的/oauth2/jwks端点
  • 在Keycloak服务器上通过curl命令测试JWK端点的连通性,排查网络隔离、防火墙或反向代理导致的访问失败问题
  • 若Spring Authorization Server启用HTTPS,需确保Keycloak信任其SSL证书,否则会因证书验证失败无法拉取密钥

2. 规范Spring Authorization Server的密钥配置

  • 避免动态生成的密钥随服务重启变更:配置持久化密钥存储(如JdbcKeyStore),或固定kid值,示例配置如下:
    @Bean
    public JWKSource<SecurityContext> jwkSource() {
        RSAKey rsaKey = generateRsaKey();
        JWKSet jwkSet = new JWKSet(rsaKey);
        return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
    }
    
    private static RSAKey generateRsaKey() {
        KeyPair keyPair = generateRsaKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        // 使用固定字符串作为kid,避免重启后变更
        return new RSAKey.Builder(publicKey)
                .privateKey(privateKey)
                .keyID("fixed-key-id-123")
                .build();
    }
    
  • 确认JWKSource配置中包含对应签名算法的密钥,且alg字段与JWT使用的签名算法(如RS256)一致

3. 重置Keycloak的密钥缓存

  • 进入Keycloak控制台,找到对应IDP,点击Save重新保存配置,触发JWK的重新拉取
  • 调整Keycloak的JWK缓存过期时间:在配置文件中修改keycloak.keys.infinispan.cache-ttl参数,缩短缓存周期
  • 手动清除缓存:重启Keycloak服务,或通过管理API清空Infinispan中的旧密钥存储

4. 验证签名算法匹配性

  • 确认Spring Authorization Server生成的JWT签名算法,与JWK中声明的alg字段、Keycloak IDP配置的签名算法完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 22:52:46