web-dev-qa-db-de.com

Behandeln von Zertifikatsfehlern in Android Webview und Löschen der Zertifikatseinstellungen

Ich versuche, einen geeigneten Weg zur Behandlung von SSL-Zertifikatfehlern in der Android-Webansicht zu finden. Mein Ziel ist es, Seiten mit SSL-Zertifikatfehlern zu laden. Der Benutzer kann jedoch die Seite nach der Warnung laden about security jedes Mal, wenn er versucht, eine URL mit Zertifikatfehlern zu laden .

Die nächsten Lösungen, die ich in Threads gefunden habe, schlagen vor, den WebViewClient wie folgt zu überschreiben:

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

Dies deaktiviert jedoch grundsätzlich SSL im WebView ohne die Zustimmung des Benutzers.

Hier sind die Threads, in denen ich diese Lösung gefunden habe:

Android WebView SSL 'Sicherheitswarnung'

Unterstützt die Webansicht auf Android SSL?

Android WebView lädt keine HTTPS-URL

Android-Webansicht mit Client-Zertifikat

Webansicht zeigt leere Seite nach dem Laden der URL bei Verwendung von WIFI in Android }

Eine bestimmte Webseite kann nicht in Android-Webansicht geladen werden.

WebView zeigt für bestimmte Links eine leere Ansicht

Android WebView blockiert die Umleitung von https zu http

SSL-Zertifikatsanforderungen in Webview ignorieren

Ich ging voran und implementierte eine etwas andere Version, die den Benutzer auffordert:

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();
                }
            });
    }
});

Bei dieser Implementierung wird der Benutzer zweimal gefragt, ob er die Seite laden möchte. Wenn er zweimal Ja sagt, wird der Fehler ignoriert und die Seite wird geladen, andernfalls wird das Laden der Seite abgebrochen.

Beim ersten Laden einer URL mit Zertifikatfehler wird WebViewClient.onReceivedSslError aufgerufen. Wenn der Benutzer jedoch mit dem Zertifikatfehler fortfährt und SslErrorHandler.proceed() aufgerufen wird, werden die folgenden Zeiten die gleiche URL geladen, WebViewClient.onReceivedSslError wird nie wieder aufgerufen: Durch das Beenden der App wird dieses Verhalten zurückgesetzt.

Ich möchte, dass WebViewClient.onReceivedSslError systematisch aufgerufen wird, wenn eine URL mit einem Zertifikatfehler geladen wird, nicht nur beim ersten Mal. Ich habe versucht, diese Methoden ohne Erfolg aufzurufen:

/** 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();

Weiß jemand, wie der WebView-Code WebViewClient.onReceivedSslError mehr als einmal für dieselbe URL aufgerufen werden soll, nachdem SslErrorHandler.proceed() aufgerufen wurde?

14
androidseb

Überschreiben Sie niemals die onReceivedSslError-Methode. Google Play lehnt Ihren Upload am intelligentesten ab, indem Sie SSL-Fehler behandeln. webSettings.setDomStorageEnabled(true);

3

Ja, Sie können clearSslPreferences () wie hier verwenden:

webView.clearSslPreferences()

Dadurch wird Ihre Entscheidung für dieses WebView-Objekt klar

1
Djek-grif

Ich werde nur die Antwort posten, die Tssomas in den Kommentaren der ursprünglichen Frage gegeben hat, denn nach all dieser Zeit ist es die einzige Lösung, die zuverlässig funktioniert, auch wenn es ein Hack ist.

Tssomas zitiert:

Wenn der Benutzer fortfährt, wird seine Vorliebe, trotzdem fortzufahren, nur Für diese Sitzung beibehalten (wenn er die App schließt und erneut startet, wird der Dialog Erneut angezeigt). Um sicherzugehen, dass der Benutzer den Dialog Jedes Mal sieht, musste ich die ungesicherte URL zu einer Array-Liste hinzufügen und einen - Check hinzufügen, damit jedes Mal, wenn der Webview das Laden beendet, die Array-Liste wird auf die aktuelle URL der Webansicht geprüft. Wenn also die Array-Liste Die aktuelle URL enthält, zeigen Sie den Dialog an. Es ist keine Hübsche Lösung, aber es funktioniert ...

So könnte der Code aussehen ...

//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
androidseb