2012-01-20 10 views
15

Ho studiato e ricercato e ricercato questo fino a che non sono diventato grigio e calvo. Come diavolo faccio a ottenere un WebView a lavorare per un sito che ha bisogno di autenticazione HTTP di base tramite una connessione HTTPS a livello di API 8+webview android con connessione https e autenticazione di base. Come farlo funzionare?

Ho il seguente codice

String email = Util.getEmail(this); 
    String pwd = Util.getPassword(this); 
    webview.getSettings().setJavaScriptEnabled(true); 
    webview.setHttpAuthUsernamePassword(Config.SERVER_BASE_URL, "Application", email, pwd); 

//  webview.setWebViewClient(new MobileWebViewClient(this)); 
    webview.loadUrl(url); 

Come potete vedere ho fatto avere un client vista web (Ora commentata) che ridefinisce il metodo onReceivedHttpAuthRequest che assomiglia a questo

@Override 
public void onReceivedHttpAuthRequest (WebView view, HttpAuthHandler handler, String host, String realm){ 
    String email = Util.getEmail(wvContext); 
    String pwd = Util.getPassword(wvContext); 
    if(!pwd.equalsIgnoreCase("-1") && !pwd.equalsIgnoreCase("-1")){ 
     handler.proceed(email, pwd); 
    } 
} 

questo è stato utilizzato senza il webview.setHttpAuthUsernamePassword e funziona bene, tranne che significa 2 richieste vengono emesse al w ebsite - Il primo ottiene un 401 e poi il client entra in gioco con il roba di autorizzazione Questo va bene per una piccola quantità di traffico sul sito Web, ma dimezzare la quantità di traffico (attualmente con una media di 49 richieste p/m) è il nome del gioco in questo momento !

Ho letto che posso preventivamente fornire le credenziali utilizzando

webview.setHttpAuthUsernamePassword(Config.SERVER_BASE_URL, "Application", email, pwd); 

Tuttavia questo solo si traduce in HTTP di base: Accesso negato errori La costante di base del server URL è il nome di dominio per il sito cioè https://example.com (senza la pagina) l'url effettivo è https://example.com/some_pages. Non fa differenza se utilizzo l'url completo o il dominio. Ho controllato il regno e l'ho corretto e ho usato solo stringhe vuote fornendo solo e-mail e password. Questo potrebbe essere qualcosa a che fare con il fatto che il sito utilizza https? Il mio codice sembra funzionare bene sul mio box di sviluppo senza https ma potrebbe essere una falsa pista.!

Le uniche domande di overflow dello stack che sembrano coprire i miei requisiti non hanno risposte accettate e i documenti non sono di alcun aiuto che io possa vedere.

Ora ho una tale ammaccatura nella mia testa da sbattere contro un muro di mattoni che sto pensando di ottenere un cappello quadrato.

Per favore, se qualcuno mi può dare la soluzione a questo sarò per sempre in debito con te! Potrei persino inviarti un e-Mail KitKat

+0

Io lo prendo [questa domanda e la sua risposta accettata] (http://stackoverflow.com/questions/1968416/how-to-do-http-authentication-in-android) non risolve il problema ? –

+0

@aaamos, Potrebbe benissimo risolvere il mio problema, ma come potrei applicarlo a una WebView? – jamesc

+0

Hai provato a scaricare la pagina Web con un httppost e quindi a fornirla a una visualizzazione Web? – Warpzit

risposta

15

Questo semplice esempio abusa di una pagina su HttpWatch poiché è più divertente con un esempio pubblico funzionante.

La risorsa in questione, https://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?randomgarbage utilizza autenticazione di base su HTTPS e può essere caricato senza errore di autenticazione come questo (testato utilizzando 2.3.7 Android):

WebView v = ...; // Your webview goes here. 
    try { 
     HashMap<String, String> map = new HashMap<String, String>(); 
     // This test service takes the username "httpwatch" and a random 
     // password. Repeating a password can lead to failure, so we create 
     // a decently random one using UUID. 
     String usernameRandomPassword = "httpwatch:" + UUID.randomUUID().toString(); 
     String authorization = "Basic " + Base64.encodeToString(usernameRandomPassword.getBytes("UTF-8"), Base64.NO_WRAP); 
     map.put("Authorization", authorization); 
     v.loadUrl("https://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?" + System.currentTimeMillis(), map); 
    } catch (UnsupportedEncodingException e) {} 

Questo funziona su ICS e Gingerbread. Non ho accesso a qualcosa di più vecchio, ma loadUrl(String, Map<String,String>) è stato introdotto nel livello API 8, quindi non vedo perché non dovrebbe funzionare per quello.

Chiarimento per Nappy:

per supportare l'autenticazione per le richieste successive si fornisce un WebViewClient e procedere come segue:

webView.setWebViewClient(new WebViewClient(){ 
     @Override 
     public boolean shouldOverrideUrlLoading(WebView view, String url) { 
      view.loadUrl(url, <your map containing the Authorization header>); 
      return true; 
     } 
    }); 
+0

Grazie per la risposta, funziona sicuramente ma sono preoccupato che le credenziali vengano visualizzate nell'URL del browser che non è assolutamente quello di cui ho bisogno per questa particolare soluzione. Quindi ho bisogno di sapere se c'è comunque che le credenziali potrebbero 'perdere' in un modo che l'utente sarebbe in grado di vederle? – jamesc

+1

La mappa è un insieme di intestazioni HTTP che verranno incluse nella risposta: in pratica, trucchi la WebView per includere l'intestazione che verrebbe inviata se si è passati alla richiesta iniziale non riuscita e * quindi * ha risposto con credenziali valide. - quindi non fa parte dell'URL. – Jens

+0

È grandioso! Lo stesso può essere applicato a un DefaultHTTPClient? – jamesc

1

Essa opererà per https URL.In questo caso stiamo ottenendo Untrusted_cer allora avremo ignorarlo

webview.setWebViewClient(new WebViewClient(){ 
     @Override 
     public void onReceivedHttpAuthRequest(WebView view, 
       HttpAuthHandler handler, String host, String realm) { 
      super.onReceivedHttpAuthRequest(view, handler, host, realm); 
     } 

     @Override 
     public void onReceivedSslError(WebView view, 
       SslErrorHandler handler, SslError error) { 
      super.onReceivedSslError(view, handler, error); 
      if(error.getPrimaryError()==SslError.SSL_UNTRUSTED){ 
       handler.proceed(); 
      }else{ 
       handler.proceed(); 
      } 
     } 

    }); 

Non ho idea circa secondo problema

+0

@james: hai risolto il tuo primo problema? – Sameer

+0

Non ne sono ancora sicuro, sto verificando le cose e sia la tua soluzione combinata con la soluzione di @Jens sembra essere esattamente ciò di cui ho bisogno, ma sto lottando con un'ultima cosa. Sto per aggiungere un commento alla risposta di Jens a riguardo. Come potrei dividere la taglia tra voi due? – jamesc

+0

@jamesw: dirò di darmelo :) – Sameer

0

per la gestione delle autorizzazioni sul tuo sito, basta eseguire l'override del metodo seguente nella vostra webViewClient e aggiungere il nome utente e la password nel suo gestore.

@Override 
     public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) { 
      handler.proceed(StringUtils.AUTH_NAME,StringUtils.AUTH_PASS); 
     } 
Problemi correlati