1. 概述
在这个教程中,我们将学习如何创建并配置一个OkHttpClient以信任所有证书。有关OkHttp的更多详细信息,请参阅我们的相关文章。
2. Maven依赖
首先,让我们在pom.xml
文件中添加OkHttp的依赖:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>5.0.0-alpha.12</version>
</dependency>
3. 使用标准的OkHttpClient
首先,我们使用一个标准的OkHttpClient对象,尝试调用一个证书已过期的网页:
OkHttpClient client = new OkHttpClient.Builder().build();
client.newCall(new Request.Builder().url("https://expired.badssl.com/").build()).execute();
输出堆栈跟踪如下:
sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
现在,当我们尝试另一个使用自签名证书的网站时,会看到错误:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
接着,尝试一个证书与主机名不匹配的网站:
Hostname wrong.host.badssl.com not verified
如你所见,默认情况下,OkHttpClient会在调用证书有问题的网站时抛出错误。接下来,我们将学习如何创建并配置一个OkHttpClient来信任所有证书。
4. 设置OkHttpClient信任所有证书
让我们创建一个包含单个X509TrustManager的TrustManager数组,这个X509TrustManager通过重写其方法来禁用默认的证书验证:
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[]{};
}
}
};
我们将使用这个TrustManager数组来创建一个SSLContext:
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
然后,我们将使用这个SSLContext设置OkHttpClient构建器的SSLSocketFactory:
OkHttpClient.Builder newBuilder = new OkHttpClient.Builder();
newBuilder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]);
newBuilder.hostnameVerifier((hostname, session) -> true);
我们还将新构建器的HostnameVerifier设置为一个新的HostnameVerifier对象,其验证方法始终返回true。
最后,我们可以获取一个新的OkHttpClient对象,再次调用有问题的证书的网站,而不会出现任何错误:
OkHttpClient newClient = newBuilder.build();
newClient.newCall(new Request.Builder().url("https://expired.badssl.com/").build()).execute();
5. 总结
在这篇简短的文章中,我们了解了如何创建并配置一个OkHttpClient以信任所有证书。当然,信任所有证书并不建议,但在某些特殊情况下可能会需要。本文的完整代码可在GitHub上找到。