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

Spring Boot集成Keycloak OAuth2认证遇PKIX证书路径错误求助

问题:Spring Boot集成Keycloak OAuth2认证后登录跳转失败及PKIX证书错误

我正尝试将Spring Boot应用与Keycloak集成以实现OAuth2认证,但遇到登录后无法正常跳转的问题,同时收到如下错误信息:

[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: I/O error on POST request for "https://<KEYCLOAK_SERVER>/realms/oauth-AD/protocol/openid-connect/certs": PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

该错误在登录后显示于浏览器端。我确认Spring应用与Keycloak均已配置必要证书,现咨询该问题的原因及解决办法。

相关代码

SecurityConfig.java

public class SecurityConfig {

    @Bean
    public SecurityFilterChain setFilterChain(HttpSecurity http) throws Exception {

        http
                .csrf(AbstractHttpConfigurer::disable)
                .oauth2Client(Customizer.withDefaults())
                .oauth2Login(Customizer.withDefaults())
                .authorizeHttpRequests((authorizeHttpRequests) -> authorizeHttpRequests
                        .requestMatchers(new AntPathRequestMatcher("/role/visiter")).hasRole("ROLE_VISITER")

                        .requestMatchers(new AntPathRequestMatcher("/index/**")).permitAll()
                        .anyRequest().authenticated());
        return http.build();
    }

    @Bean
    public ClientRegistrationRepository clientRegistrationRepository() {
        ClientRegistration dummyRegistration = ClientRegistration.withRegistrationId("keycloak-oauth2")
                .clientId("dummy-client-id")
                .clientSecret("dummy-client-secret")
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .redirectUri("https://localhost:8443/login/oauth2/code/keycloak")
                .issuerUri("https://keycloak.example.com/realms/myrealm")
                .authorizationUri("https://keycloak.example.com/realms/myrealm/protocol/openid-connect/auth")
                .scope("openid", "email", "profile", "roles")
                .tokenUri("https://keycloak.example.com/realms/myrealm/protocol/openid-connect/token")
                .userInfoUri("https://keycloak.example.com/realms/myrealm/protocol/openid-connect/userinfo")
                .jwkSetUri("https://keycloak.example.com/realms/myrealm/protocol/openid-connect/certs")
                .build();
        return new InMemoryClientRegistrationRepository(dummyRegistration);
    }

}

application.properties

spring.application.name=demo

#Server Konfiguration
server.port=8443
server.error.whitelabel.enabled=false
server.error.path=/error

# Logging Configuration
logging.level.org.springframework.security=DEBUG

#Keystore
server.ssl.enabled=true
server.ssl.key-store=classpath:localhost.jks
server.ssl.key-store-type=jks
server.ssl.key-store-password=<password>
server.ssl.protocol=TLSv1.3

#Truststore
server.ssl.trust-store=classpath:localhost.jks
server.ssl.trust-store-type=jks
server.ssl.trust-store-password=<password>

注:Keycloak服务器名称及SSL密码已做脱敏处理,目前尚未找到解决办法。


问题原因

核心问题是Java信任库未包含Keycloak服务器的SSL证书:

  • 你的配置中server.ssl.trust-store使用的是localhost.jks,该密钥库仅包含本地服务的证书,未添加Keycloak服务器的根证书或中间证书。
  • 当Spring Boot应用请求Keycloak的/certs端点获取JWK证书链时,JVM无法验证Keycloak的HTTPS连接合法性,触发PKIX路径构建失败。

解决办法

1. 导出Keycloak服务器的SSL证书

在命令行执行以下命令(替换<KEYCLOAK_SERVER>和<PORT>为实际地址):

openssl s_client -connect <KEYCLOAK_SERVER>:<PORT> </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > keycloak.crt

2. 将证书导入Spring Boot的信任库

使用keytool命令将导出的证书添加到localhost.jks信任库(替换<PASSWORD>和<ALIAS>为实际值):

keytool -importcert -alias <ALIAS> -file keycloak.crt -keystore localhost.jks -storepass <PASSWORD>

执行时会提示是否信任该证书,输入yes确认。

3. 验证信任库内容(可选)

检查证书是否成功导入:

keytool -list -keystore localhost.jks -storepass <PASSWORD>

4. 简化配置(可选)

Spring Boot 2.4+支持通过issuerUri自动发现Keycloak端点,无需手动指定authorizationUri、tokenUri等,减少配置错误:

@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
    ClientRegistration dummyRegistration = ClientRegistration.withRegistrationId("keycloak-oauth2")
            .clientId("dummy-client-id")
            .clientSecret("dummy-client-secret")
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .redirectUri("https://localhost:8443/login/oauth2/code/keycloak")
            .issuerUri("https://keycloak.example.com/realms/myrealm")
            .scope("openid", "email", "profile", "roles")
            .build();
    return new InMemoryClientRegistrationRepository(dummyRegistration);
}

5. 重启应用测试

重新启动Spring Boot应用,再次尝试登录流程,验证跳转是否正常、错误是否消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 18:22:43