前言
在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);
}
對你有幫助記得點贊❥(^_-)