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
相关产品推荐
相关产品推荐

