2016-02-05 41 views
12

Sto cercando di trovare un modo corretto di gestire gli errori del certificato SSL nel Webview Android. Il mio obiettivo è quello di fornire un modo per caricare le pagine con gli errori del certificato SSL, ma lasciare che l'utente sceglie di caricare la pagina dopo di lui avvertimento circa la sicurezza ogni volta che tenta di caricare un URL con errori del certificato.Gestione degli errori del certificato di Android Webview e deselezionando le peferences certificato

Le soluzioni che ho trovato più vicini a discussioni suggeriscono ignorando l'WebViewClient come segue:

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

Tuttavia questo disabilita fondamentalmente SSL in WebView senza il consenso dell'utente.

Per riferimento qui sono i fili dove ho trovato questa soluzione:

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

sono andato avanti e implementato una versione leggermente diversa, che richiede all'utente:

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

Questa implementazione richiede all'utente due volte se h e vuole caricare la pagina, se dice due volte sì, quindi l'errore viene ignorato e la pagina viene caricata, altrimenti il ​​caricamento della pagina viene annullato.

La prima volta che un URL con carichi di errore del certificato, WebViewClient.onReceivedSslError si chiama, se l'utente procede con l'errore di certificato e SslErrorHandler.proceed() è chiamato, con i seguenti orari gli stessi carichi URL, WebViewClient.onReceivedSslError non è mai chiamato di nuovo: solo uccidendo l'applicazione ripristina questo comportamento.

vorrei WebViewClient.onReceivedSslError di essere chiamato sistematicamente quando un URL con carichi di errore certificato, non solo la prima volta. Ho provato a chiamare quei metodi senza successo:

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

Qualcuno sa come fare la chiamata WebView WebViewClient.onReceivedSslError più di una volta per lo stesso URL, dopo SslErrorHandler.proceed() è stato chiamato?

+0

hai qualche soluzione?> –

+0

No Non ho ancora trovato nessuna soluzione. – androidseb

+0

@KingofMasses la notte impiega così tanto tempo nel tuo paese? sto scherzando, puoi pubblicare per favore? ho bisogno di questo ... – user2582318

risposta

0

Sì, è possibile utilizzare clearSslPreferences() come qui:

webView.clearSslPreferences() 

Sarà cancellare la vostra decisione per questo oggetto di WebView

2

Non bisogna mai ignorare onReceivedSslError metodo.Goole play rifiuterà il tuo upload modo più intelligente è gestire l'errore SSL uso webSettings.setDomStorageEnabled(true);

+0

Grazie mille fratello, Google Play ha rifiutato il mio aggiornamento a causa di questo problema, ma è stato appena accettato quando si imposta 'setDomStorageEnabled' su' true' –

+1

@MahmoudElshamy sei benvenuto fratello felice ha funzionato :-) –

+0

Grazie. questo funziona e è stato testato. –

0

Inserirò solo la risposta che Tssomas ha fornito nei commenti della domanda originale, perché dopo tutto questo tempo, è l'unica soluzione che funziona in modo affidabile anche se è un hack.

Citando Tssomas:

Se l'utente procede, la loro preferenza per andare avanti comunque viene mantenuta solo per quella sessione (se chiudono l'applicazione e iniziare di nuovo la finestra di si ri-spettacolo). Quindi, ho fatto in modo che l'utente vedesse la finestra di dialogo ogni volta che aggiungeva l'url non sicuro a un elenco di array e aggiungeva un controllo in modo che ogni volta che la webview termina il caricamento, l'elenco di array viene controllato per l'URL corrente della webview . Così poi, naturalmente, se la lista di array contiene l'URL corrente, visualizzare la finestra .. la sua non è una bella soluzione a tutti, ma funziona ...

Questo è come il codice potrebbe essere simile ..

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