Apache HttpClient 配置 SSL 证书指南

Apache HttpClient 配置 SSL 证书指南

概述

在使用 Apache HttpClient 进行 HTTPS 请求时,有时需要配置自定义的 SSL 证书以建立安全连接。本文介绍如何为 HttpClient 配置 SSL 证书,特别是从 classpath 加载 .crt 证书文件的场景。

应用场景

  • 连接使用自签名证书的服务器
  • 企业内网环境中的 HTTPS 服务调用
  • 需要双向认证的安全连接
  • 数据库(如 Doris)的 SSL 连接

核心实现步骤

1. 添加 Maven 依赖

xml 复制代码
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version>
</dependency>

2. 加载证书文件

从 classpath 读取证书文件并生成证书对象:

java 复制代码
// 从 resources 目录读取 .crt 证书文件
InputStream is = new ClassPathResource("certs/server.crt").getInputStream();

// 生成 X509 证书对象
Certificate cert = CertificateFactory.getInstance("X.509")
    .generateCertificate(is);

3. 构建 KeyStore

将证书装入 Java KeyStore:

java 复制代码
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
trustStore.setCertificateEntry("my_cert", cert);

4. 创建 SSLContext

使用 KeyStore 构建 SSL 上下文:

java 复制代码
SSLContext sslContext = SSLContextBuilder.create()
    .loadTrustMaterial(trustStore, null)
    .build();

5. 配置 HttpClient

将 SSL 配置注册到连接管理器:

java 复制代码
// 创建 SSL 连接工厂
SSLConnectionSocketFactory sslSocketFactory =
    new SSLConnectionSocketFactory(sslContext);

// 注册 HTTP 和 HTTPS 协议
Registry<ConnectionSocketFactory> registry =
    RegistryBuilder.<ConnectionSocketFactory>create()
        .register("http", PlainConnectionSocketFactory.getSocketFactory())
        .register("https", sslSocketFactory)
        .build();

// 创建连接管理器
PoolingHttpClientConnectionManager connManager =
    new PoolingHttpClientConnectionManager(registry);

// 构建 HttpClient
CloseableHttpClient httpClient = HttpClients.custom()
    .setConnectionManager(connManager)
    .build();

完整示例代码

java 复制代码
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;

import javax.net.ssl.SSLContext;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

public class HttpClientSSLConfig {

    public CloseableHttpClient createSSLHttpClient(String certPath) throws Exception {
        // 1. 加载证书
        InputStream is = new ClassPathResource(certPath).getInputStream();
        Certificate cert = CertificateFactory.getInstance("X.509")
            .generateCertificate(is);

        // 2. 构建 KeyStore
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);
        trustStore.setCertificateEntry("server_cert", cert);

        // 3. 创建 SSLContext
        SSLContext sslContext = SSLContextBuilder.create()
            .loadTrustMaterial(trustStore, null)
            .build();

        // 4. 配置连接管理器
        SSLConnectionSocketFactory sslSocketFactory =
            new SSLConnectionSocketFactory(sslContext);

        Registry<ConnectionSocketFactory> registry =
            RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", sslSocketFactory)
                .build();

        PoolingHttpClientConnectionManager connManager =
            new PoolingHttpClientConnectionManager(registry);

        // 5. 构建 HttpClient
        return HttpClients.custom()
            .setConnectionManager(connManager)
            .build();
    }
}

使用示例

java 复制代码
// 创建配置了 SSL 的 HttpClient
CloseableHttpClient httpClient = createSSLHttpClient("certs/server.crt");

// 发起 HTTPS 请求
HttpGet request = new HttpGet("https://example.com/api");
CloseableHttpResponse response = httpClient.execute(request);

// 处理响应
int statusCode = response.getStatusLine().getStatusCode();
String responseBody = EntityUtils.toString(response.getEntity());

注意事项

  1. 证书路径 :确保证书文件放在 src/main/resources 目录下
  2. 异常处理:生产环境中需要妥善处理各类异常(IOException、CertificateException 等)
  3. 连接池配置:可根据实际需求配置连接池参数(最大连接数、超时时间等)
  4. 资源释放:使用完毕后记得关闭 HttpClient 和 Response 对象
  5. 证书格式 :支持 .crt.pem 等 X.509 格式证书

常见问题

Q: 如何配置双向认证(mTLS)?

需要同时配置 trustStore(服务端证书)和 keyStore(客户端证书):

java 复制代码
SSLContext sslContext = SSLContextBuilder.create()
    .loadTrustMaterial(trustStore, null)
    .loadKeyMaterial(keyStore, keyPassword)
    .build();

Q: 如何跳过证书验证(仅用于开发环境)?

java 复制代码
SSLContext sslContext = SSLContextBuilder.create()
    .loadTrustMaterial(null, (chain, authType) -> true)
    .build();

警告:生产环境中不要跳过证书验证!

总结

通过以上步骤,我们可以为 Apache HttpClient 配置自定义 SSL 证书,实现安全的 HTTPS 通信。这种方式特别适用于企业内网环境或需要使用自签名证书的场景。


参考资源

相关推荐
格鸰爱童话2 小时前
向AI学习项目技能(三)
java·人工智能·python·学习
浩宇软件开发2 小时前
springBoot+Vue中华诗词学习后台管理系统
vue.js·spring boot·axios·element-plus·router
weixin199701080162 小时前
南网商城商品详情页前端性能优化实战
java·前端·性能优化
iPadiPhone2 小时前
Spring Boot 自动装配原理与 Starter 开发实战
java·spring boot·后端·spring·面试
SuGarSJL2 小时前
FakeSMTP-2.1.1使用
java·maven
码匠君2 小时前
首个基于 Spring Boot 4 的正式版发布!Dante Cloud 4.X 新特性全解析
java·spring boot·后端
阿豪学编程2 小时前
【网络】应用层-HTTP协议
网络·网络协议·http
悟空码字2 小时前
SpringBoot + 百度地图SDK,打造企业级位置服务中台
java·百度·地图·编程技术·后端开发