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

Spring Boot 3.4.1:如何配置SSLBundle与RestClient协同工作?

问题

我正在使用Spring Boot 3.4.1、JDK 23和MySQL 9,对Spring Framework新版本的RestClient特性很感兴趣。之前已经通过RestTemplate成功实现了双向TLS(mutualTLS),现在希望在RestClient中配置SSLBundle(若无法实现则使用SSLContext)。

以下是我的配置文件和代码:

application.yml

server:
  port: 8001
  ssl:
      bundle: bar
      client-auth: NEED
      enabled: true
spring:
    datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/fuu001?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
        username: ggAABB
        password: fg33435
    ssl:
        bundle:
            jks:
                foo:
                    keystore:
                        location: C:\\ssl\\server-identity.p12
                        password: fdfd
                        type: PKCS12
                    truststore:
                        location: C:\\ssl\\server-truststore.p12
                        password: fg54533
                        type: PKCS12
                    reload-on-update: true
                bar:
                    keystore:
                        location: C:\\ssl\\client-identity.p12
                        password: dfdsfs
                        type: PKCS12
                    truststore:
                        location: C:\\ssl\\client-truststore.p12
                        password: 4573d@
                        type: PKCS12
                    reload-on-update: true
    jpa:
        hibernate:
          ddl-auto: create-drop
        properties:
          hibernate:
              format_sql: true
        show-sql: true
#    security:
#      user:
#          name: user
#          password: g5643544

CallFooService.java

package com.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@Service
public class CallFooService {

    @Autowired
    private RestTemplate restTemplate;

    public void testMethod(){
        String response = restTemplate.getForObject("https://localhost:8001/user", String.class);
        System.out.println("response = " + response);

        String response2 = restTemplate.getForObject("https://localhost:8002/user", String.class);
        System.out.println("response2 = " + response2);


        RestClient defaultClient = RestClient.create();

        RestClient customClient = RestClient.builder()
                .requestFactory(new HttpComponentsClientHttpRequestFactory()) // 我想在此处注入SSLBundle或SSL Context
                .messageConverters(converters -> converters.add(null))
                .baseUrl("https://example.com")
                .defaultUriVariables(Map.of("variable", "foo"))
                .defaultHeader("My-Header", "Foo")
                .defaultCookie("My-Cookie", "Bar")
                .requestInterceptor(null)
                .requestInitializer(null)
                  // 我想在此处注入SSLBundle或SSL Context
                .build();
    }

}

请问如何在Spring Boot 3.4.1中配置SSLBundle与RestClient协同工作?


解决方案

在Spring Boot 3.4.1中,你可以直接复用已配置的SSLBundle来构建支持双向TLS的RestClient,步骤如下:

1. 注入目标SSLBundle

Spring Boot会自动将配置文件中定义的SSLBundle注册为Bean,你可以通过@Autowired结合@Qualifier注入指定的bundle(比如foo或bar):

@Autowired
@Qualifier("foo") // 替换为你需要使用的bundle名称,比如"bar"
private SSLBundle sslBundle;

2. 基于SSLBundle构建请求工厂

RestClient需要配置ClientHttpRequestFactory来启用SSL,你可以通过以下几种方式将SSLBundle集成进去:

方式一:使用SimpleClientHttpRequestFactory(轻量实现)

直接从SSLBundle提取SSLContext和HostnameVerifier,配置到SimpleClientHttpRequestFactory:

// 从SSLBundle获取SSL上下文和主机名验证器
SSLContext sslContext = sslBundle.createSslContext();
HostnameVerifier hostnameVerifier = sslBundle.getHostnameVerifier();

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setSslContext(sslContext);
requestFactory.setHostnameVerifier(hostnameVerifier);

方式二:使用HttpComponentsClientHttpRequestFactory(Apache HttpClient实现)

如果需要更复杂的HTTP配置(比如连接池),可以结合Apache HttpClient:

SSLContext sslContext = sslBundle.createSslContext();
// 构建支持SSL的HttpClient
CloseableHttpClient httpClient = HttpClientBuilder.create()
        .setSSLContext(sslContext)
        .setSSLHostnameVerifier(sslBundle.getHostnameVerifier())
        .build();

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);

方式三:使用Spring工具类快速构建(推荐)

Spring Boot提供了ClientHttpRequestFactories工具类,可以直接从SSLBundle生成请求工厂,简化代码:

ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(
        ClientHttpRequestFactories.Options.sslBundle(sslBundle)
);

3. 构建配置好SSL的RestClient

将上面生成的requestFactory传入RestClient.builder即可:

RestClient customClient = RestClient.builder()
        .requestFactory(requestFactory)
        .baseUrl("https://localhost:8002") // 替换为目标服务地址
        .defaultHeader("My-Header", "Foo")
        .defaultCookie("My-Cookie", "Bar")
        // 其他配置保持不变
        .build();

关键说明

  • 复用Spring Boot的SSLBundle配置后,无需手动加载证书文件,且配置中开启的reload-on-update: true会自动生效,证书更新时无需重启应用。
  • 双向TLS的验证逻辑完全由SSLBundle中的keystore(客户端身份)和truststore(信任的服务端证书)控制,和你之前RestTemplate的配置逻辑一致。

内容的提问来源于stack exchange,提问作者Đỗ Như Vỹ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 02:22:32