SpringBoot_minio sdk使用自签名https证书错误处理

news/2025/1/15 23:06:00/

minio sdk使用自签名https证书错误处理

  • 1.问题描述
    • 1.1 报错日志
    • 1.2 maven 依赖配置
    • 1.3 当前spring MinioClient配置
  • 2.问题分析
  • 3.问题解决
    • 3.1 使用受信任的证书
    • 3.2 忽略证书验证
      • 3.2.1 minio客户端
      • 3.2.2 minio sdk 忽略证书验证
        • 3.2.2.1 拓展: 补充minioclient请求日志
  • 4. 问题总结
  • 5.附录

1.问题描述

minio 8.4.4 使用自签名的https的api连接会报错证书错误

1.1 报错日志

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

1.2 maven 依赖配置

        <!--minio java sdk--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.4</version><exclusions><exclusion><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.10.0</version></dependency>

1.3 当前spring MinioClient配置

@Configuration
@EnableConfigurationProperties(MinioProperties.class)
public class MinioConfig {@Beanpublic MinioClient minioClient(MinioProperties properties){properties.check();return MinioClient.builder().endpoint(properties.getEndpoint()).credentials(properties.getAccessKey(), properties.getSecretKey()).build();}
}

2.问题分析

通常是因为MinIO默认情况下会验证服务器的TLS证书。在生产环境中,使用自签名证书并不推荐,因为它们不受信任的证书颁发机构(CA)签署,可能会导致安全问题。

3.问题解决

3.1 使用受信任的证书

为了在生产环境中确保安全性,建议获取一个受信任的SSL证书,可以从证书颁发机构(CA)购买,或者使用免费的证书颁发机构(例如Let’s Encrypt)获取SSL证书。

3.2 忽略证书验证

3.2.1 minio客户端

在MinIO客户端(例如mc命令行工具)中,可以使用–insecure选项来忽略证书验证。例如:

mc --insecure <command>

这会告诉MinIO客户端不要验证服务器的TLS证书。请注意,这种做法会降低安全性,不建议在生产环境中使用。

3.2.2 minio sdk 忽略证书验证

在使用Java SDK与自签名证书的服务器进行通信时,一般可以通过自定义SSLContext来忽略证书验证。

MinIO的Java SDK(version 8.0.6及以上)允许自定义OkHttpClient,我们可以使用httpClient方法传递一个自定义的OkHttpClient实例。以便在HTTP、正常HTTPS和自签名HTTPS之间实现兼容性

下面是如何使用自定义的OkHttpClient实现对HTTP、正常HTTPS和自签名HTTPS的兼容性

@Configuration
@EnableConfigurationProperties(MinioProperties.class)
public class MinioConfig {private static final Logger LOGGER = LoggerFactory.getLogger(MinioConfig.class);@Beanpublic MinioClient minioClient(MinioProperties properties){properties.check();// Create a trust manager that does not validate certificate chainsTrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}public void checkClientTrusted(X509Certificate[] certs, String authType) {// Do nothing (trust any client certificate)}public void checkServerTrusted(X509Certificate[] certs, String authType) {// Do nothing (trust any server certificate)}}};// Install the all-trusting trust managerSSLContext sslContext = null;try {sslContext = SSLContext.getInstance("SSL");sslContext.init(null, trustAllCerts, new java.security.SecureRandom());} catch (Exception e) {LOGGER.error("Install the all-trusting trust manager error:{}", e.getMessage());}// Create a custom OkHttpClient that trusts all certificatesOkHttpClient customHttpClient = new OkHttpClient.Builder().sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]).hostnameVerifier((hostname, session) -> true).build();// Set the custom SSLContext for MinioClientreturn MinioClient.builder().endpoint(properties.getEndpoint()).credentials(properties.getAccessKey(), properties.getSecretKey()).httpClient(customHttpClient).build();}}
  1. 在上面的代码中,我们创建了一个SSLContext,其中的X509TrustManager会信任所有证书,无论其是否由信任的证书颁发机构(CA)签署。
  2. 创建了一个自定义的OkHttpClient,该客户端信任所有证书。然后,我们使用MinioClient.builder()方法,将自定义的OkHttpClient传递给httpClient()方法

这种方法会将所有证书都视为受信任的,因此请仅在非生产环境中使用此方法,以确保通信的安全性和完整性。在生产环境中,建议使用受信任的SSL证书。

3.2.2.1 拓展: 补充minioclient请求日志

之前minioclient与服务器端交互使用默认的httpclient的客户端,请求没有打印详细日志. 既然上面自定义自己的httpclient那么可以补充自定义拦截器打印日志

public class CustomLoggingInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();long startTime = System.nanoTime();System.out.println("Sending request " + request.url() + " on " + chain.connection() + "\n" + request.headers());Response response = chain.proceed(request);long endTime = System.nanoTime();System.out.println("Received response for " + response.request().url() + " in " + ((endTime - startTime) / 1e6) + "ms\n" + response.headers());MediaType contentType = response.body().contentType();String content = response.body().string();System.out.println("Response body:\n" + content);ResponseBody wrappedBody = ResponseBody.create(contentType, content);return response.newBuilder().body(wrappedBody).build();}
}

修改MinioConfig增加okhttp拦截器

        // Create a custom OkHttpClient that trusts all certificatesOkHttpClient customHttpClient = new OkHttpClient.Builder().sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]).hostnameVerifier((hostname, session) -> true).addInterceptor(new CustomLoggingInterceptor()) // Add custom interceptor here.build();

效果
在这里插入图片描述

4. 问题总结

minio客户端本质使用httpclient与服务端交互,因此证书问题处理其实只是httpclient对证书的兼容处理。该处理方式可以运用到其他使用到httpclient的场景。

5.附录

代码优化

@Configuration
@EnableConfigurationProperties(MinioProperties.class)
public class MinioConfig {private static final Logger LOGGER = LoggerFactory.getLogger(MinioConfig.class);@Beanpublic MinioClient minioClient(MinioProperties properties){properties.check();OkHttpClient customHttpClient = null;if (properties.getEndpoint().startsWith("https://")) {// 如果是HTTPS,使用自定义的OkHttpClient处理自签名的HTTPS请求customHttpClient = createCustomOkHttpClient();}MinioClient minioClient;if (customHttpClient != null) {// 如果使用了自定义的OkHttpClientminioClient = MinioClient.builder().endpoint(properties.getEndpoint()).credentials(properties.getAccessKey(), properties.getSecretKey()).httpClient(customHttpClient).build();} else {// 如果是普通HTTP,使用默认的OkHttpClientminioClient = MinioClient.builder().endpoint(properties.getEndpoint()).credentials(properties.getAccessKey(), properties.getSecretKey()).build();}return minioClient;}/*** Set the custom SSLContext for MinioClient* @return*/private static OkHttpClient createCustomOkHttpClient() {// 创建自定义的OkHttpClient,用于处理自签名的HTTPS请求// Create a trust manager that does not validate certificate chainsTrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}public void checkClientTrusted(X509Certificate[] certs, String authType) {// Do nothing (trust any client certificate)}public void checkServerTrusted(X509Certificate[] certs, String authType) {// Do nothing (trust any server certificate)}}};// Install the all-trusting trust managerSSLContext sslContext = null;try {sslContext = SSLContext.getInstance("SSL");sslContext.init(null, trustAllCerts, new java.security.SecureRandom());} catch (Exception e) {LOGGER.error("Install the all-trusting trust manager error:{}", e.getMessage());}// Create a custom OkHttpClient that trusts all certificatesOkHttpClient customHttpClient = new OkHttpClient.Builder().sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]).hostnameVerifier((hostname, session) -> true)// 增加minio http请求日志打印//.addInterceptor(new CustomLoggingInterceptor()) // Add custom interceptor here.build();return customHttpClient;}}

http://www.ppmy.cn/news/1172088.html

相关文章

04.Finetune vs. Prompt

目录 语言模型回顾大模型的两种路线专才通才二者的比较 专才养成记通才养成记Instruction LearningIn-context Learning 自动Prompt 部分截图来自原课程视频《2023李宏毅最新生成式AI教程》&#xff0c;B站自行搜索 语言模型回顾 GPT&#xff1a;文字接龙 How are __. Bert&a…

关于阿里云服务器续费详细流程_优惠续费方法

阿里云服务器如何续费&#xff1f;续费流程来了&#xff0c;在云服务器ECS管理控制台选择续费实例、续费时长和续费优惠券&#xff0c;然后提交订单&#xff0c;分分钟即可完成阿里云服务器续费流程&#xff0c;阿里云服务器网分享阿里云服务器详细续费方法&#xff0c;看这一篇…

http post协议实现简单的rpc协议,WireShark抓包分析

文章目录 1.http 客户端-RPC客户端1.http 服务端-RPC服务端3.WireShark抓包分析3.1客户端到服务端的HTTP/JSON报文3.2服务端到客户端的HTTP/JSON报文 1.http 客户端-RPC客户端 import json import requests# 定义 RPC 客户端类 class RPCClient:def __init__(self, server_url…

【Docker从入门到入土 3】Docker镜像的创建方法

Part3 一、Docker镜像1.1 镜像的概念1.2 镜像结构的分层 二、Docker镜像的创建2.1 基于现有镜像创建2.1.1 创建思路2.1.2 举个例子 2.2 基于本地模板创建2.3 基于Dockerfile 创建 三、Dockerfile 详解3.1 Dockerfile 操作指令3.1.1 常用的操作指令3.1.2 CMD和ENTRYPOINT的区别…

Kafka快速入门(最新版3.6.0)

文章目录 一、初识MQ1.1 什么是MQ1.2 同步和异步通讯1.1.1 同步通讯1.1.2 异步通讯 1.3 技术对比1.4 MQ的两种模式 二、初识Kafka2.1 Kafka的使用场景2.2 Kafka基本概念2.3 Topic与Partition 三、Kafka基本使用3.1 部署前的准备3.2 启动kafka服务器3.3 Kafka核心概念之Topic3.4…

【问题记录】解决Qt连接MySQL报“QMYSQL driver not loaded”以及不支持MySQL事务操作的问题!

环境 Windows 11 家庭中文版&#xff0c;64 位操作系统, 基于 x64 的处理器Qt 5.15.2 MinGW 32-bitmysql Ver 14.14 Distrib 5.7.42, for Win32 (AMD64) 问题情况 在Qt 5.15.2 中编写连接MySQL数据库代码后&#xff0c;使用 MinGW 32-bit 构建套件进行编译运行后&#xff0c;报…

LVS负载均衡及LVS-NAT模式

一、集群概述 1.1 集群的背景 集群定义&#xff1a;为解决某个特定问题将多个计算机组合起来形成一个单系统 集群目的&#xff1a;为了解决系统的性能瓶颈 集群发展历史&#xff1a; 垂直扩展&#xff1a;向上扩展&#xff0c;增加单个机器的性能&#xff0c;即升级硬件 水…

原型链继承

方式一&#xff1a;原型链继承 1.套路&#xff1a; &#xff08;1&#xff09;定义父类型构造函数 &#xff08;2&#xff09;给父类型的原型添加方法 &#xff08;3&#xff09;定义子类型的构造函数 &#xff08;4&#xff09;创建父类型的对象赋值给子类型的原型 &…