Android WebviewでSSL証明書エラーを処理する適切な方法を見つけようとしています。私の目標は、SSL証明書エラーのあるページをロードする方法を提供することですが、ユーザーがセキュリティについて警告した後のページ証明書エラーのあるURLをロードしようとするとき。
スレッドで見つけた最も近いソリューションは、次のようにWebViewClientをオーバーライドすることをお勧めします。
_webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(final WebView view, final SslErrorHandler handler, final SslError error) {
handler.proceed();
}
});
_
ただし、これは基本的にユーザーの同意なしにWebViewのSSLを無効にします。
参考までに、私がその解決策を見つけたスレッドを次に示します。
Android WebViewがHTTPS URLをロードしない
AndroidでWIFIを使用している場合、URLのロード後にWebビューに空白/白いページが表示されます
Android webview で特定のWebページをロードできません
WebViewは特定のリンクに対して空白のビューを表示します
Android WebViewはhttpsからhttpへのリダイレクトをブロックします
私は先に進み、ユーザーにプロンプトを出すわずかに異なるバージョンを実装しました:
_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();
}
});
}
});
_
この実装は、ページをロードするかどうかをユーザーに2回尋ねます。yesを2回言うと、エラーは無視されてページがロードされます。それ以外の場合、ページのロードはキャンセルされます。
証明書エラーのある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
_を複数回行う方法を誰かが知っていますか?
OnReceivedSslErrorメソッドをオーバーライドしないでください。 Google Playはアップロードを拒否します。最も賢い方法はSSLエラーを処理することですwebSettings.setDomStorageEnabled(true);
はい、次のようにclearSslPreferences()を使用できます。
webView.clearSslPreferences()
WebViewのこのオブジェクトに対する決定をクリアします
Tssomasが元の質問のコメントで提供した答えを投稿します。これは結局のところ、それがハックであっても確実に機能する唯一のソリューションだからです。
Tssomasの引用:
ユーザーが続行すると、先に進むという彼らの好みはそのセッションの間のみ維持されます(ユーザーがアプリを閉じて再度起動した場合、ダイアログが再表示されます)。したがって、ユーザーがダイアログを毎回確実に表示するために行ったのは、セキュリティで保護されていないURLを配列リストに追加し、Webビューの読み込みが完了するたびに配列リストのWebビューの現在の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);
}
});