首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理Android中的证书错误和清除证书引用

处理Android中的证书错误和清除证书引用
EN

Stack Overflow用户
提问于 2016-02-05 21:44:21
回答 3查看 16.2K关注 0票数 16

我正在试图找到一种正确的方法来处理Android中的SSL证书错误。我的目标是提供一种方法来加载带有SSL证书错误的页面,但允许用户在试图加载包含证书错误的URL时,在警告他安全性后加载页面。

我在线程中找到的最接近的解决方案建议重写WebViewClient如下:

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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,而不仅仅是第一次。我试着给这些方法打电话,但没有成功:

代码语言:javascript
复制
/** 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();

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

EN

回答 3

Stack Overflow用户

发布于 2017-11-15 11:02:33

不要重写onReceivedSslError方法。Goole play将拒绝您的上传。最聪明的方法是处理SSL错误,使用webSettings.setDomStorageEnabled(true)

票数 8
EN

Stack Overflow用户

发布于 2017-11-09 15:55:23

是的,您可以像下面这样使用clearSslPreferences():

代码语言:javascript
复制
webView.clearSslPreferences()

它将为WebView的这个对象澄清您的决定

票数 2
EN

Stack Overflow用户

发布于 2017-11-16 15:48:43

我将只发布Tssoma在最初问题的评论中给出的答案,因为经过这么长时间,这是唯一可靠的解决方案,即使它是一个黑客。

引用Tssoma的话:

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

这就是代码的样子..。

代码语言:javascript
复制
//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);
    }
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35234074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档