【问题标题】:Android WebView load https url results in blank screenAndroid WebView 加载 https url 导致空白屏幕
【发布时间】:2017-08-24 19:04:20
【问题描述】:

WebView 可以很好地处理 http 请求以及 https 以及众所周知的受信任站点,例如 https://www.online.citibank.co.in/ 但是我尝试使用第三方颁发的 CA 访问私人站点,它给出了空白屏幕。证书通过 SD 卡安装到手机并列在受信任的证书列表中。

当我在将证书添加到 TrustManager 后使用 HttpsURLConnection 尝试相同的 URL 时,它工作正常(能够获取内容)。

以下是 WebView 和 HttpsURLConnection 的代码 sn-p。

HttpsURLConnection:下面的代码工作正常,并且能够从 URL 中获取内容(我无法共享 URL,因为它无法从外部世界访问)

try
{
    SSLContext context = null;

    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    InputStream caInput = getResources().openRawResource(R.raw.mi_net);
    Certificate ca;
    try {
        ca = cf.generateCertificate(caInput);
    } finally {
        caInput.close();
    }

    // Create a KeyStore containing our trusted CAs
    String keyStoreType = KeyStore.getDefaultType();
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", ca);

    // Create a TrustManager that trusts the CAs in our KeyStore
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keyStore);

    // Create an SSLContext that uses our TrustManager
    context = SSLContext.getInstance("TLS");
    context.init(null, tmf.getTrustManagers(), null);

    url = new URL(urlStr);
    HttpsURLConnection con = (HttpsURLConnection) url.openConnection();  
    con.setSSLSocketFactory(context.getSocketFactory());
    con.setInstanceFollowRedirects(true);

    con.setDoOutput(false);
    con.setConnectTimeout(1000);
    String responseMsg = con.getResponseMessage();
    response = con.getResponseCode();
    is = con.getInputStream();
}

WebView:不工作,调用回调onReceivedSslError

{
    WebSettings viewSettings = webView.getSettings();
    viewSettings.setJavaScriptEnabled(true);
    viewSettings.setAllowContentAccess(true);
    viewSettings.setBuiltInZoomControls(false);
    webView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
    webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
    webView.loadUrl(sameURL);

    webView.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageStarted(final WebView view, final String url, Bitmap favicon) {
            Log.d("ann", "onPageStarted");

        }

        @Override
        public void onPageFinished(final WebView view, String url) {
            Log.d("ann", "inside onPageFinished");
        }

        @Override
        public void onReceivedError(WebView view, int errorCode,
                                    String description, String failingUrl) {

            if (!failingUrl.startsWith("mailto:")) {
                webView.loadUrl("file:///android_asset/html/error.html");
            }

        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler,
                                       SslError error) {
            super.onReceivedSslError(view, handler, error);
            Log.d("ann","SSL error");

            handler.proceed();
        }

    });}
}

请帮我提出建议。 WebViewClient 异常是 I/X509Util:无法验证证书链,错误:java.security.cert.CertPathValidatorException:找不到证书路径的信任锚。

【问题讨论】:

    标签: android ssl webview


    【解决方案1】:

    对于 HttpsUrlConnection,您从文件创建证书并在运行时设置它。

    Webview 必须使用系统中已经存在的任何内容。

    这是一个类似的问题,提出了解决方法:

    Check in the onReceivedSslError() method of a WebViewClient if a certificate is signed from a specific self-signed CA

    【讨论】:

    • @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { // super.onReceivedSslError(view, handler, error); Log.d("ann","SSL 错误"); handler.proceed(); } 在评论了超级功能之后,事情开始为我工作了。
    • 请注意,此解决方法可让您绕过证书检查,您应该处理逻辑以再次检查您作为文件包含的证书。否则就像不使用 https。
    猜你喜欢
    • 1970-01-01
    • 2011-07-15
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    相关资源
    最近更新 更多