如何在Spring Boot中配置声明式RestClient信任所有证书?
Spring Boot 3.2.5 声明式RestClient信任所有证书配置方案
问题场景
基于Spring Boot 3.2.5,使用RestClient结合HttpExchange开发声明式REST客户端,调试阶段需要绕过证书验证以提升效率(明确仅用于调试,不适用生产环境)。
解决方案
核心思路是自定义ClientHttpRequestFactory,配置信任所有证书的SSL上下文和主机名验证器,再整合到原有的RestClient配置流程中,保留声明式客户端的用法。
步骤1:实现信任所有证书的请求工厂
在FooClientConfig中添加方法,生成忽略证书验证的SimpleClientHttpRequestFactory:
private ClientHttpRequestFactory buildTrustAllCertRequestFactory(ProxyConfig proxyConfig) { SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); // 保留原有代理配置逻辑 if (proxyConfig.isEnabled()) { InetSocketAddress socketAddress = new InetSocketAddress(proxyConfig.getAddress(), proxyConfig.getPort()); Proxy proxy = new Proxy(proxyConfig.getSchema(), socketAddress); requestFactory.setProxy(proxy); } try { // 创建信任所有证书的SSLContext SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) {} @Override public void checkServerTrusted(X509Certificate[] chain, String authType) {} @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}, new SecureRandom()); // 设置忽略主机名匹配验证 requestFactory.setSslContext(sslContext); requestFactory.setHostnameVerifier((hostname, session) -> true); } catch (NoSuchAlgorithmException | KeyManagementException e) { log.error("配置信任所有证书的SSL上下文失败", e); throw new RuntimeException(e); } return requestFactory; }
步骤2:整合到RestClient配置流程
修改buildNativeClient方法,根据调试配置选择对应的请求工厂,同时避免与原有SSL Bundle配置冲突:
@Bean public FooClient buildNativeClient(RestClient.Builder builder, RestClientSsl ssl, NativeProperties properties) { var baseUrl = buildBaseUrl(properties.getSsl().isEnabled(), properties.getHost(), properties.getHostPort(), properties.getBaseUrl()); builder.baseUrl(baseUrl) .defaultHeaders(httpHeaders -> httpHeaders.setBasicAuth( properties.getBasicAuth().getUsername(), properties.getBasicAuth().getPassword())); // 仅在未开启信任所有证书时,应用原有SSL Bundle配置 if (properties.getSsl().isEnabled() && !properties.getSsl().isTrustAll()) { builder.apply(ssl.fromBundle(properties.getSsl().getBundle())); } // 根据配置选择请求工厂 ClientHttpRequestFactory requestFactory = properties.getSsl().isTrustAll() ? buildTrustAllCertRequestFactory(properties.getProxy()) : buildRequestFactory(properties.getProxy()); var restClient = builder .requestFactory(requestFactory) .build(); return HttpServiceProxyFactory .builderFor(RestClientAdapter.create(restClient)) .build() .createClient(FooClient.class); }
步骤3:添加调试配置开关
在NativeProperties中新增SSL信任开关(或直接在配置文件中定义),比如在application-dev.yml中添加:
native: ssl: enabled: true trust-all: true # 仅调试环境开启
关键注意事项
- 禁止生产环境启用:此配置完全绕过证书验证,存在严重安全风险
- 配置隔离:通过环境配置开关控制,确保生产包中不会开启该功能
- 冲突避免:信任所有证书的配置与原有SSL Bundle配置互斥,需通过条件判断排除冲突
内容的提问来源于stack exchange,提问作者Alois Šenkyřík
相关产品推荐
相关产品推荐

