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

如何在使用Spring SslBundle的SpringBoot RestClient中禁用SSL验证(信任不安全主机)

如何在使用Spring SslBundle的SpringBoot RestClient中禁用SSL验证(信任不安全主机)

嘿,我完全懂你的需求——你已经靠RestClient+SslBundle成功发了客户端证书给第三方,但现在想跳过对他们服务器证书的验证,还不想退回到老掉牙的RestTemplate。之前你试着删掉truststore配置,结果发现根本不等于用InsecureTrustManagerFactory,对吧?确实,Spring不会自动帮你切换到不安全的信任管理器,得咱们手动配置才行。

下面给你两种可行的方案,全都是基于SslBundle的,完全不用碰RestTemplate:


方案一:基于现有SslBundle构建自定义「不安全」Bundle(推荐)

这个思路很简单:保留你已经配置好的keystore(毕竟还要给第三方发客户端证书),但把信任管理器换成「信任所有证书」的实现,同时跳过主机名验证。

步骤1:保留配置文件的keystore配置

你的配置文件不用改,就用你之前修改后的版本(只留keystore,删掉truststore):

spring:
  ssl:
    bundle:
      jks:
        mybundle:
          keystore:
            location: C:\\ssl\\keystore.p12
            password: 123
            type: PKCS12
          reload-on-update: true

步骤2:创建自定义的不安全SslBundle Bean

我们基于原有的mybundle,构建一个新的SslBundle,替换掉信任管理器和主机名验证器:

import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.net.ssl.InsecureTrustManagerFactory;
import javax.net.ssl.NoopHostnameVerifier;

@Configuration
public class InsecureSslConfig {

    @Bean
    public SslBundle insecureSslBundle(SslBundles sslBundles) {
        // 获取我们配置的只包含keystore的原始bundle
        SslBundle originalKeystoreBundle = sslBundles.getBundle("mybundle");
        
        // 构建新的不安全Bundle:保留keystore,替换信任和主机名验证逻辑
        return SslBundle.builder()
                .from(originalKeystoreBundle)
                // 信任所有证书(对应InsecureTrustManagerFactory.INSTANCE)
                .trustManagerFactory(() -> InsecureTrustManagerFactory.INSTANCE)
                // 跳过主机名验证(信任任何主机名)
                .hostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build();
    }
}

步骤3:在RestClient中使用这个不安全的Bundle

修改你的RestClient Bean,用咱们自定义的insecureSslBundle:

@Bean
public RestClient restClient(RestClient.Builder builder, SslBundle insecureSslBundle) {
    return builder.baseUrl("https://the-secure-api.com/api")
            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
            .apply(RestClientSsl.fromBundle(insecureSslBundle))
            .build();
}

方案二:直接在RestClient Bean中内联构建不安全Bundle(更简洁)

如果不想单独写一个SslBundle Bean,也可以直接在RestClient的配置里内联完成,效果完全一样:

@Bean
public RestClient restClient(RestClient.Builder builder, SslBundles sslBundles) {
    // 获取原始keystore bundle
    SslBundle originalBundle = sslBundles.getBundle("mybundle");
    
    // 内联构建不安全Bundle
    SslBundle insecureBundle = SslBundle.builder()
            .from(originalBundle)
            .trustManagerFactory(() -> InsecureTrustManagerFactory.INSTANCE)
            .hostnameVerifier(NoopHostnameVerifier.INSTANCE)
            .build();
            
    return builder.baseUrl("https://the-secure-api.com/api")
            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
            .apply(RestClientSsl.fromBundle(insecureBundle))
            .build();
}

关键说明&注意事项

  1. 为什么之前的方法没用?
    当你只配置keystore而不配置truststore时,Spring会默认用系统的信任库(比如JDK的cacerts),而不是自动切换到不安全的信任管理器。所以必须显式指定InsecureTrustManagerFactory才行。

  2. Spring版本兼容性

    • 如果你用Spring Boot 3.2+,可以用SslTrustManagerFactories.insecure()代替() -> InsecureTrustManagerFactory.INSTANCE,用SslHostnameVerifiers.NONE代替NoopHostnameVerifier.INSTANCE——这俩是Spring封装的便捷方法,更贴合Spring的API风格。
    • 3.1及以下版本就用上面代码里的InsecureTrustManagerFactory和NoopHostnameVerifier就行。
  3. 安全警告!!!
    这个配置绝对只能在测试/开发环境用!生产环境禁用SSL验证会让你的请求完全暴露在中间人攻击(MITM)的风险下,后果不堪设想。


内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 08:44:27