Spring Boot集成Keycloak遇SSLHandshakeException问题求助
解决Keycloak SSL握手异常(PKIX路径构建失败)
问题根源
你的Spring Boot应用JVM未信任OpenShift上Keycloak服务器的SSL证书,导致加载OpenID配置时触发证书验证失败。浏览器/Postman能正常访问是因为它们的信任库已包含该证书,但JVM默认信任库没有。
方案1:开发环境临时信任所有证书(仅用于测试)
仅作为开发阶段快速验证的临时方案,禁止生产环境使用。通过自定义SSLContext让应用跳过证书验证:
创建Spring Security配置类,覆盖Keycloak的SSL处理逻辑:
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; import org.keycloak.adapters.springsecurity.KeycloakConfiguration; import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.security.cert.X509Certificate; @KeycloakConfiguration public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter { static { try { // 初始化信任所有证书的TrustManager TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkClientTrusted(X509Certificate[] certs, String authType) {} @Override public void checkServerTrusted(X509Certificate[] certs, String authType) {} } }; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); } catch (Exception e) { e.printStackTrace(); } } @Bean public KeycloakSpringBootConfigResolver keycloakConfigResolver() { return new KeycloakSpringBootConfigResolver(); } @Override protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new NullAuthenticatedSessionStrategy(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { KeycloakAuthenticationProvider authProvider = keycloakAuthenticationProvider(); authProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); auth.authenticationProvider(authProvider); } @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); http.authorizeRequests() .anyRequest().authenticated(); } }
方案2:生产环境合规解决(推荐)
生产环境必须通过导入合法证书到JVM信任库来解决,绝对不能信任所有证书。
步骤1:导出Keycloak的SSL证书
- 方法一:用OpenSSL命令
openssl s_client -connect example.com:443 </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > keycloak.crt - 方法二:浏览器导出
访问https://example.com/auth,点击地址栏锁图标 → 查看证书 → 导出为Base64编码的.crt文件。
步骤2:导入证书到JVM信任库
JVM默认信任库路径:$JAVA_HOME/jre/lib/security/cacerts(JDK 8及以下)或$JAVA_HOME/lib/security/cacerts(JDK 11+),默认密码为changeit。
执行导入命令:
keytool -import -alias keycloak-cert -file keycloak.crt -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
提示是否信任时输入yes确认。
备选:使用自定义信任库
如果不想修改全局JVM信任库,可创建自定义信任库:
keytool -import -alias keycloak-cert -file keycloak.crt -keystore custom-truststore.jks -storepass your-custom-password
启动Spring Boot应用时添加JVM参数:
java -jar your-app.jar -Djavax.net.ssl.trustStore=custom-truststore.jks -Djavax.net.ssl.trustStorePassword=your-custom-password
额外注意
你的application.properties中keycloak.ssl-required=none仅控制是否强制SSL连接,不影响证书验证逻辑,无需修改该配置。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

