[Java]OKHttp/HttpsURLConnection请求出现PKIX path building failed的解决(跳过证书验证)

2021-05-12 2680点热度 0人点赞 0条评论

最近一个项目中Java中用OKHttp/HttpsURLConnection请求一个https的API,出现如下报错:

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

用Postman或者浏览器模拟请求,却是正常的,也不是网上查到的所谓的证书问题。

因为实在检查不出来什么原因(也有可能是服务器在防火墙里面被档了什么),索性让OKHttp跳过证书验证,问题解决。

准备如下方法:

/*
 * This is very bad practice and should NOT be used in production.
 * 最好不要用在生产环境
 */
private static final TrustManager[] trustAllCerts = new TrustManager[] {
        new X509TrustManager() {
            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
            }

            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
            }

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[]{};
            }
        }
};
private static final SSLContext trustAllSslContext;
static {
    try {
        trustAllSslContext = SSLContext.getInstance("SSL");
        trustAllSslContext.init(null, trustAllCerts, new java.security.SecureRandom());
    } catch (NoSuchAlgorithmException | KeyManagementException e) {
        throw new RuntimeException(e);
    }
}
public static final SSLSocketFactory trustAllSslSocketFactory = trustAllSslContext.getSocketFactory();
public static OkHttpClient trustAllSslClient(OkHttpClient client) {
    OkHttpClient.Builder builder = client.newBuilder();
    builder.sslSocketFactory(trustAllSslSocketFactory, (X509TrustManager)trustAllCerts[0]);
    //java8以上用的lambda,如果也可以用下面的代码
    builder.hostnameVerifier((hostname, session) -> true);
//        builder.hostnameVerifier(new HostnameVerifier() {
//            @Override
//            public boolean verify(String hostname, SSLSession session) {
//                return true;
//            }
//        });
    return builder.build();
}

OKHttp的调用方法:

OkHttpClient client = Utils.trustAllSslClient(new OkHttpClient().newBuilder().build());
Request request = new Request.Builder().url(config.getResourceLocation() + "?access_token=" + accessToken).build();
Response response = client.newCall(request).execute();
String string = response.body().string();

如果用HttpsURLConnection这样调用:

URL url = new URL("https://example.com/api/test");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(Utils.trustAllSslSocketFactory);
conn.setHostnameVerifier((s, sslSession) -> true);

 

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论