J'essaie de trouver un moyen approprié de gérer les erreurs de certificat SSL dans la vue Web Android. Mon objectif est de fournir un moyen de charger les pages avec des erreurs de certificat SSL, mais laissez l'utilisateur choisir de charger la page après l'avoir averti. à propos de la sécurité chaque fois qu'il essaie de charger une URL avec des erreurs de certificat .
Les solutions les plus proches que j'ai trouvées dans les discussions suggèrent de remplacer le WebViewClient comme suit:
webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(final WebView view, final SslErrorHandler handler, final SslError error) {
handler.proceed();
}
});
Cependant, cela désactive fondamentalement SSL dans WebView sans le consentement de l'utilisateur.
Pour référence, voici les discussions où j'ai trouvé cette solution:
Android WebView SSL 'Avertissement de sécurité'
Web View sur Android prend-il en charge SSL?
Android WebView ne charge pas une URL HTTPS
Webview Android avec certificat client
Impossible de charger une page Web spécifique sur la vue Web Android
WebView affiche une vue vierge pour certains liens
Android WebView bloque la redirection de https vers http
Ignorer les demandes de certificats SSL dans la visualisation Web
Je suis allé de l'avant et ai implémenté une version légèrement différente qui invite l'utilisateur:
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();
}
});
}
});
Cette implémentation demande deux fois à l'utilisateur s'il veut charger la page, s'il dit oui deux fois, l'erreur est ignorée et la page est chargée, sinon le chargement de la page est annulé.
La première fois qu'une URL avec une erreur de certificat est chargée, WebViewClient.onReceivedSslError
est appelé. Toutefois, si l'utilisateur continue avec l'erreur de certificat et que SslErrorHandler.proceed()
est appelé, les temps suivants où la même URL est chargée, WebViewClient.onReceivedSslError
n'est jamais appelé à nouveau: le seul fait de supprimer l'application résout ce problème.
Je voudrais que WebViewClient.onReceivedSslError
soit appelé systématiquement lorsqu’une URL avec une erreur de certificat se charge, pas seulement la première fois. J'ai essayé d'appeler ces méthodes sans succès:
/** 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();
Est-ce que quelqu'un sait comment appeler WebView WebViewClient.onReceivedSslError
plusieurs fois pour la même URL après l'appel de SslErrorHandler.proceed()
?
Ne jamais remplacer la méthode onReceivedSslError. Google Play refusera votre envoi de la manière la plus intelligente est de gérer l'utilisation des erreurs SSL webSettings.setDomStorageEnabled(true);
Oui, vous pouvez utiliser clearSslPreferences () comme ici:
webView.clearSslPreferences()
Ça va effacer votre décision pour cet objet de WebView
Je vais simplement publier la réponse que Tssomas a donnée dans les commentaires de la question initiale, car après tout ce temps, c'est la seule solution qui fonctionne de manière fiable, même si c'est un bidouillage.
Citant Tssomas:
Si l'utilisateur continue, sa préférence pour continuer de toute façon n'est conservée que Pour cette session (s'il ferme l'application et la redémarre, la boîte de dialogue Réapparaîtra). Donc, ce que j’ai fait pour que l’utilisateur voie la boîte de dialogue À chaque fois a été d’ajouter l’URL non sécurisée à une liste de tableaux et d’ajouter une vérification De sorte que chaque fois que la vue Web se charge complètement, la liste de tableaux est cochée pour l'URL actuelle de la webview. Alors, bien sûr, si la liste de tableaux Contient l’URL actuelle, affichez la boîte de dialogue .. ce n’est pas une jolie solution Mais ça fonctionne ...
Voici à quoi pourrait ressembler le code ...
//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);
}
});