2016-02-05 3 views
12

J'essaie de trouver un moyen approprié de gérer les erreurs de certificat SSL dans l'Android Webview. Mon objectif est de fournir un moyen de charger des pages avec des erreurs de certificat SSL, mais laissez l'utilisateur choisir de charger la page après l'avoir averti de la sécurité chaque fois qu'il essaie de charger une URL avec des erreurs de certificat.Gestion des erreurs de certificat dans Android Webview

Les plus proches solutions que j'ai trouvé dans les discussions suggèrent redéfinissant la WebViewClient comme suit:

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

Cependant cette opération désactive essentiellement SSL dans le WebView sans le consentement de l'utilisateur.

Pour référence ici sont les fils où je trouve cette solution:

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

Je suis allé de l'avant et mis en œuvre 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 à l'utilisateur deux fois si h e veut charger la page, s'il dit oui deux fois, alors l'erreur est ignorée et la page se charge, sinon le chargement de la page est annulé.

La première fois une URL avec des charges d'erreur de certificat, WebViewClient.onReceivedSslError est appelée, si l'utilisateur procède à l'erreur de certificat et SslErrorHandler.proceed() est appelé, les temps suivant les mêmes charges d'URL, WebViewClient.onReceivedSslError est jamais appelé à nouveau: tuer seulement l'application réinitialise ce comportement.

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

Quelqu'un sait comment faire l'appel WebView WebViewClient.onReceivedSslError plus d'une fois pour la même URL, après SslErrorHandler.proceed() a été appelé?

+0

Vous avez des solutions?> –

+0

Non je n'ai encore trouvé aucune solution. – androidseb

+0

@KingofMas la nuit prend si longtemps dans votre pays? Je plaisante, pouvez-vous poster s'il vous plaît? J'ai besoin de cela ... – user2582318

Répondre

0

Oui, vous pouvez utiliser clearSslPreferences() comme ici:

webView.clearSslPreferences() 

Il va effacer votre décision pour cet objet de WebView

2

Ne jamais remplacer la méthode onReceivedSslError.Goole play va rejeter votre téléchargement le plus intelligent est de gérer l'erreur SSL utiliser webSettings.setDomStorageEnabled(true);

+0

Merci beaucoup bro, Google Play a rejeté ma mise à jour à cause de ce problème mais il est juste accepté lors de la définition de 'setDomStorageEnabled' à' true' –

+1

@MahmoudElshamy vous êtes bienvenue bro heureux que cela a fonctionné :-) –

+0

Merci. Cela fonctionne et a été testé. –

0

Je vais juste poster la réponse que Tssomas a donné dans les commentaires de la question originale, car après tout ce temps, c'est la seule solution qui fonctionne de manière fiable, même si c'est un hack.

Citant Tssomas:

Si l'utilisateur procède, leur préférence pour aller de l'avant de toute façon ne sont conservés pour cette session (s'ils ferment l'application et commencent à nouveau la dialogue reétrenner). Donc, ce que je faisais pour que l'utilisateur voit la boîte de dialogue à chaque fois était d'ajouter l'URL non sécurisée à une liste de tableaux et d'ajouter une vérification de sorte que chaque fois que le webview se termine, la liste de tableaux est vérifiée pour l'URL actuelle du webview . Alors bien sûr, si la liste de tableau contient l'URL actuelle, afficher la boîte de dialogue .. ne est pas une solution assez du tout, mais cela fonctionne ...

Voici comment le code pourrait ressembler à ..

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