前言
在Android项目开发过程中,我们目前常用到的网络框架基本都是基于Okhttp,Https协议在APP的开发中也被应用的越来越多,Okhttp默认是
支持https请求的,但是支持的Https网站必须是CA机构认证了的,对于自签名的网址,还是不能访问的,访问直接抛出如下异常信息:
onFailure: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
对于https协议的处理,目前两种方式
- 客户端默认信任全部证书
- 对自签名网址进行证书的单独处理
客户端默认信任全部证书
这个方式实现起来简单,但是因为信任了全部证书,会有一定的风险!使用者需注意,下面了解一下具体的实现
- 创建信任管理器的基本接口X509TrustManager
//获取TrustManager
private static TrustManager[] getTrustManager() {
//不校检证书链
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
//不校检客户端证书
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
//不校检服务器证书
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
//OKhttp3.0以前返回null,3.0以后返回new X509Certificate[]{};
}
}
};
return trustAllCerts;
}
2. 创建SSLSocketFactory
//获取这个SSLSocketFactory
//通过这个类我们可以获得SSLSocketFactory,这个东西就是用来管理证书和信任证书的
public static SSLSocketFactory getSSLSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, getTrustManager(), new SecureRandom());
return sslContext.getSocketFactory();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//获取HostnameVerifier
public static HostnameVerifier getHostnameVerifier() {
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
//未真正校检服务器端证书域名
return true;
}
};
return hostnameVerifier;
}
3. Okhttp相关配置
public OkHttpClient getOkHttpClient() {
if (mOkHttpClient == null) {
mOkHttpClient = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.sslSocketFactory(new SSLSocketClient().getSSLSocketFactory())//配置
.hostnameVerifier(new SSLSocketClient().getHostnameVerifier())//配置
// .readTimeout(10, TimeUnit.SECONDS)
.build();
}
return mOkHttpClient;
}
信任证书的相关配置就准备好了
扩展
- webview不能加载https图片
原因
如果您的应用是面向 API 级别 21 或更高级别:
-
默认情况下,系统会阻止混合内容和第三方 Cookie。要允许混合内容和第三方 Cookie,请分别使用
setMixedContentMode()和 setAcceptThirdPartyCookies() 方法。 -
系统现在可以智能地选择要绘制的 HTML 文档部分。这个新的默认行为有助于减少内存占用和提升性能。如果您要一次渲染整个文档,可通过调用 enableSlowWholeDocumentDraw()`停用此优化。
如果您的应用是面向低于 21 的 API 级别:
- 系统允许混合内容和第三方 Cookie,并始终一次渲染整个文档。
解决方法
//Android Lollipop(5.0)开始 webview默认不允许混合模式,https当中不能加载http资源,如果要加载,需单独设置开启。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
对你有帮助记得点赞❥(^_-)