背景
1、我们项目要集成到第三方平台上,访问方式使用的是https,开始集成是minio服务器是http,上传和下载过程中会出现不安全的问题。后面把minio服务改为https。如何改自行百度。
2、但是在我们使用minio https服务的过程中,因为我们使用的SSL证书是自己生成的,下载文件可以,但是在上传文件是会发生
PKIX path building failed 的问题。
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
通过跟源码发现是不信任的证书问题导致,new MinioClient() 一般是封装好的网络连接。
网上有一般有两种方法解决:
1、一种是下载证书,在客户端导入证书,也就是我们的jdk导入证书,但是我自己导入过还是不行(可能是我这边涉及到多个证书,但其实我都导入了,最后还是不行。) 这个导入我觉得很不方便,如果我换一台服务器,意味着证书之类的要重新导入。
2、通过代码,取消SSL验证。
这里主要是讲第二种。
由于出问题的地方就是http链接,这块,我们抓住minioclient是如何进行https链接,从这里着手。
new MinioClient(),一般初始化会传入 链接,账号和密码,但是我们这里要用的是在链接的时候就把安全验证这一步去掉,看看源码进去,new minio有多个重载方法,最后发现
这不正是我们想要的吗,只要在初始化httpclient的时候去掉ssl验证即可。直接上代码
去掉SSL验证
直接代码,OKhttpClient去掉ssl验证连接
public static OkHttpClient getUnsafeOkHttpClent() throws KeyManagementException {
try {
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}
};
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new SecureRandom());
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
return builder.build();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
Minio使用
//去掉ssl验证
OkHttpClient okHttpClient = SslUtils.getUnsafeOkHttpClent();
// MinioClient minioClient = new MinioClient(minioUrl, minioName, minioPass);
MinioClient minioClient = new MinioClient(minioUrl,9000 ,minioName, minioPass,
null,true,okHttpClient);
这样就解决了SSL证书验证的问题,希望对大家有帮助。