1. 程式人生 > >技術文章 | Android Webview場景下防止dns劫持的探索

技術文章 | Android Webview場景下防止dns劫持的探索

本文來源於阿里雲-雲棲社群,原文點選這裡

是避免dns劫持的一種有效手段,在許多特殊場景如、等都有最佳實踐,但在webview場景下卻一直沒完美的解決方案。

攔截方案是目前已知的一種在webview上應用httpdns的可行方案,本文從攔截方案的基本原理出發,嘗試分析該方案背後存在的侷限,並給出一些可行性上的建議。

基本原理

攔截方案是指通過對webview進行配置WebViewClient來做到對網路請求的攔截:

void setWebViewClient (WebViewClient client);

攔截方案的的呼叫流程如下圖所示:

Webview相關的網路請求由系統的chromium網路庫發起,Webview

呼叫loadUrl方法時,chromium網路庫會構造URLRequest例項,經過c層到java層,最終請求引數會回撥給上層WebViewClientshouldInterceptRequest方法,而我們的目標是在shouldInterceptRequest方法中通過HTTPDNS進行URL中域名到ip的替換,並且構造和返回合法的WebResourceResponse,讓webview在避免dns劫持的同時,也能正常地進行展示。

侷限

首先,當Android API < 21時,WebViewClient提供的攔截API如下:

public WebResourceResponse shouldInterceptRequest
(WebView view, String url)
;

此時shouldInterceptRequest只能拿到URL,而請求方法、頭部等這些資訊是拿不到的,強行攔截會造成請求資訊的丟失,由此可知侷限1:

侷限1:Android API < 21只能攔截網路請求的URL,請求方法、請求頭等無法攔截;

其次,對於Android API >= 21的情況,其攔截API為:

public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request);

第2個引數變成了WebResourceRequest

,其結構如下:

public interface WebResourceRequest {
    Uri getUrl();
    boolean isForMainFrame();
    boolean isRedirect();
    boolean hasGesture();
    String getMethod();
    Map<String, String> getRequestHeaders();
}

相比之下WebResourceRequest能給的多了MethodHeader以及是否重定向,但是沒有Body,也無法預知該請求是否可能攜帶body,對於帶body的符合協議但非標的Get請求一樣無法攔截,因此侷限2:

 展開全文