【问题标题】:Handling certificate errors in Android Webview and clearing the certificate peferences处理 Android Webview 中的证书错误并清除证书首选项
【发布时间】:2016-02-05 21:44:21
【问题描述】:

我正在尝试找到一种正确的方法来处理 Android Webview 中的 SSL 证书错误。 我的目标是提供一种加载带有 SSL 证书错误的页面的方法,但让用户在警告他安全性任何时候尝试加载带有证书错误的 URL 后让用户选择加载页面。。 p>

我在线程中找到的最接近的解决方案建议覆盖 WebViewClient,如下所示:

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onReceivedSslError(final WebView view, final SslErrorHandler handler, final SslError error) {
        handler.proceed();
    }
});

但是,这基本上会在未经用户同意的情况下禁用 WebView 中的 SSL。

以下是我找到该解决方案的线程供参考:

Android WebView SSL 'Security Warning'

Does the Web View on Android support SSL?

Android WebView not loading an HTTPS URL

android webview with client certificate

Web view shows blank/white page after loading URL when using WIFI in Android

Unable to load a specific webpage on Android webview

WebView displays a blank view for certain links

Android WebView blocks redirect from https to http

Ignore ssl certificate requests in webview

我继续实施了一个稍微不同的版本,它会提示用户:

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onReceivedSslError(final WebView view, final SslErrorHandler handler, final SslError error) {
        //Showing a first confirmation dialog
        AndroidUtils.showYesNoDialog(
            //First confirmation message
            "WARNING - THIS PAGE IS NOT SECURE! Are you sure you want to continue loading it?",
            //First confirmation "YES" option runnable
            new Runnable() {
                @Override
                public void run() {
                    //Showing a second confirmation dialog
                    AndroidUtils.showYesNoDialogWithResId(
                        //Second confirmation message
                        "You chose to load an unsecure page, are you sure you want to do that?",
                        //Second confirmation "YES" option runnable
                        new Runnable() {
                            @Override
                            public void run() {
                                //Disregard the error and proceed with the bad certificate anyways
                                handler.proceed();
                            }
                        },
                        //Second confirmation "NO" option runnable
                        new Runnable() {
                            @Override
                            public void run() {
                                //Cancel loading the page with that certificate error
                                handler.cancel();
                            }
                        }
                    );
                }
            },
            //First confirmation "NO" option runnable
            new Runnable() {
                @Override
                public void run() {
                    //Cancel loading the page with that certificate error
                    handler.cancel();
                }
            });
    }
});

此实现询问用户是否要加载页面两次,如果他说两次是,则忽略错误并加载页面,否则取消页面加载。

第一次加载带有证书错误的 URL 时,会调用 WebViewClient.onReceivedSslError,但是如果用户继续遇到证书错误并调用 SslErrorHandler.proceed(),接下来会加载相同的 URL,永远不会再次调用 WebViewClient.onReceivedSslError : 仅终止应用会重置此行为。

我希望在加载带有证书错误的 URL 时系统地调用 WebViewClient.onReceivedSslError,而不仅仅是第一次。我尝试调用这些方法但没有成功:

/** JAVADOC QUOTE: Clears the SSL preferences table stored in response to proceeding with SSL certificate errors.*/
webView.clearSslPreferences();
//Those other methods I tried out of despair just in case
webView.clearFormData();
webView.clearCache(true);
webView.clearHistory();
webView.clearMatches();

在调用SslErrorHandler.proceed() 之后,是否有人知道如何为同一个 URL 多次调用 WebView WebViewClient.onReceivedSslError

【问题讨论】:

  • 你有什么解决办法吗?>
  • 不,我还没有找到任何解决方案。
  • @KingofMasses 在你的国家需要这么长时间吗?开个玩笑,可以发帖吗?我需要这个...
  • @KingofMasses,你能发布你的解决方案吗?
  • 如果用户继续,他们的偏好只会保留在该会话中(如果他们关闭应用程序并重新启动,对话框将重新显示)。因此,为了确保用户每次都能看到对话框,我所做的就是将不安全的 url 添加到数组列表中并添加一个检查,以便每次 webview 完成加载时,都会检查数组列表中 webview 的当前 url。那么当然,如果数组列表包含当前 url,则显示对话框.. 它根本不是一个漂亮的解决方案,但它可以工作......

标签: android ssl https android-webview android-security


【解决方案1】:

永远不要覆盖 onReceivedSslError 方法。 Goole play 会拒绝你的上传 最聪明的方法是处理 SSL 错误使用webSettings.setDomStorageEnabled(true);

【讨论】:

  • 非常感谢兄弟,由于这个问题,Google Play 拒绝了我的更新,但在将 setDomStorageEnabled 设置为 true 时它只是被接受了
  • @MahmoudElshamy 不客气,兄弟,很高兴它成功了 :-)
  • @ChinthakaDevinda 你能解释一下它是如何/为什么起作用的吗?这与 SSL 错误有什么关系?只是好奇而已。
  • @WitaloBenicio 我也对此一无所知,但看起来它有助于忽略 SSL 错误检查。正确的 webSettings.setDomStorageEnabled(true);仅假设启用 html5 存储功能。
【解决方案2】:

是的,您可以像这里一样使用 clearSslPreferences():

webView.clearSslPreferences()

它会清除你对这个 WebView 对象的决定

【讨论】:

    【解决方案3】:

    我将仅发布 Tssomas 在原始问题的 cmets 中给出的答案,因为经过这么长时间,它是唯一可靠的解决方案,即使它是一个 hack。

    引用 Tssomas:

    如果用户继续进行,则只会保留他们继续进行的偏好 对于该会话(如果他们关闭应用程序并再次启动它,则对话框 将重新显示)。所以我做了什么来确保用户看到对话框 每次都是将不安全的 url 添加到数组列表中并添加一个 检查以便每次 webview 完成加载时,数组列表 检查 webview 的当前 url。那么当然,如果 数组列表包含当前 url,显示对话框.. 它不是 很好的解决方案,但它确实有效......

    这就是代码的样子...

    //This has to be static because it will be reset only once the app process is killed
    private static final Set<String> unsecureURLSet = new TreeSet<>();
    
    webView.setWebViewClient(new WebViewClient() {
        @Override
        public void onReceivedSslError(final WebView view, final SslErrorHandler handler, final SslError error) {
            //Adding the insecure URL to the set
            unsecureURLSet.add(error.getUrl());
            //Showing a first confirmation dialog
            AndroidUtils.showYesNoDialog(
                //First confirmation message
                "WARNING - THIS PAGE IS NOT SECURE! Are you sure you want to continue loading it?",
                //First confirmation "YES" option runnable
                new Runnable() {
                    @Override
                    public void run() {
                        //Showing a second confirmation dialog
                        AndroidUtils.showYesNoDialogWithResId(
                            //Second confirmation message
                            "You chose to load an unsecure page, are you sure you want to do that?",
                            //Second confirmation "YES" option runnable
                            new Runnable() {
                                @Override
                                public void run() {
                                    //Disregard the error and proceed with the bad certificate anyways
                                    handler.proceed();
                                }
                            },
                            //Second confirmation "NO" option runnable
                            new Runnable() {
                                @Override
                                public void run() {
                                    //Cancel loading the page with that certificate error
                                    handler.cancel();
                                }
                            }
                        );
                    }
                },
                //First confirmation "NO" option runnable
                new Runnable() {
                    @Override
                    public void run() {
                        //Cancel loading the page with that certificate error
                        handler.cancel();
                    }
                });
        }
    
        @Override
        public boolean shouldOverrideUrlLoading(final WebView _view, final String _url) {
            if (unsecureURLSet.contains(_url)){
                //Code here should mimic the dialog in onReceivedSslError
                //And replace the "handler.proceed()" with a forced load of _url
                return true;
            }
            return super.shouldOverrideUrlLoading(_view, _url);
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-13
      • 2017-05-09
      相关资源
      最近更新 更多