2010-12-27 10 views
13

Vorrei creare una Webview Android che si connetta a un sito Web tramite una connessione protetta HTTPS con l'utilizzo delle credenziali.Impostare le credenziali su una Webview Android utilizzando la connessione HTTPS protetta

Prima difficoltà era accettare il certificato (privato), è stato risolto con post this molto utile.

Seconda difficoltà è usare le credenziali, ho trovato il post this.

(prima risposta da dparnas) che sembra funzionare piuttosto bene, ma parla della connessione HTTP e non HTTPS. L'ho provato, ma non funziona, ho appena raggiunto la pagina del modulo di accesso senza alcun messaggio di errore, solo il normale modulo vuoto.

Ecco il mio codice:

import android.app.Activity; 
import android.net.http.SslError; 
import android.os.Bundle; 
import android.webkit.HttpAuthHandler; 
import android.webkit.SslErrorHandler; 
import android.webkit.WebView; 
import android.webkit.WebViewClient; 

public class ConnectorWebView extends Activity { 
    WebView mWebView; 
    String mUsrName; 
    String mPassC; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.connwebview); 

    // Getting info from Intent extras 
    // Get it if it s different from null 
    Bundle extras = getIntent().getExtras();    
    mUsrName = extras != null ? extras.getString("username") : null; 
    mPassC = extras != null ? extras.getString("passcode") : null; 

    mWebView = (WebView) findViewById(R.id.webview); 
    mWebView.getSettings().setJavaScriptEnabled(true); 
    mWebView.setHttpAuthUsernamePassword("myhost.com", "myrealm", mUsrName, mPassC); 

    mWebView.setWebViewClient(new WebViewClient() { 
     @Override 
     public void onReceivedHttpAuthRequest (WebView view, HttpAuthHandler handler, String host, String realm){ 
      handler.proceed(mUsrName, mPassC); 
     } 

     public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) { 
      handler.proceed() ; 
     } 
     }); 

    mWebView.loadUrl("https://myhost.com/secured_area"); 
    } 
} 

risposta

3

La classe WebView non fornisce la massima flessibilità nella sua connettività, come utilizzare le classi di basso livello (come HttpPost o simili) direttamente.

Se è necessario controllare completamente la connessione al server o gestire scenari di autorizzazione complicati come questo, utilizzare le classi di basso livello, recuperare i dati, quindi utilizzare WebView.loadData() per caricare e visualizzare l'HTML.

Here è un buon esempio di caricamento del contenuto tramite SSL e BasicCredentialProvider. Il risultato di questo potrebbe essere caricato nel WebView come descritto sopra.

+0

Non sembra che ci saranno altre risposte quindi ti assegnerò la taglia.Nessun punto nel perdere :) –

+0

"scenari di autorizzazione complicati" hahahahhah, questo è completamente standard RFC da anni fa, webview dovrebbe gestire questo ... – Nappy

+0

mentre sono d'accordo che "dovrebbe" - e vorrei che lo farebbe! - La webview espone solo un determinato sottoinsieme del comportamento supportato dalla libreria HTTP completa ... – elijah

13

Poiché sembra che WebView non può nativamente gestire l'autenticazione Basic utilizzando HTTPS, ho iniziato giocando con l'idea di impostare la Authorization intestazione (contenente il nome utente/password codificata) manualmente.

Ecco come credo che questo può essere fatto:

import org.apache.commons.codec.binary.Base64; 

// ... 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.connwebview); 

    // Getting info from Intent extras 
    // Get it if it s different from null 
    Bundle extras = getIntent().getExtras();    
    mUsrName = extras != null ? extras.getString("username") : null; 
    mPassC = extras != null ? extras.getString("passcode") : null; 

    mWebView = (WebView) findViewById(R.id.webview); 
    mWebView.getSettings().setJavaScriptEnabled(true); 
    // mWebView.setHttpAuthUsernamePassword("myhost.com", 
    //         "myrealm", 
    //         mUsrName, 
    //         mPassC); 

    mWebView.setWebViewClient(new WebViewClient() { 
     @Override 
     public void onReceivedHttpAuthRequest(WebView view, 
              HttpAuthHandler handler, 
              String host, 
              String realm){ 
     handler.proceed(mUsrName, mPassC); 
     } 

     public void onReceivedSslError(WebView view, 
            SslErrorHandler handler, 
            SslError error) { 
     handler.proceed() ; 
     } 
    }); 

    String up = mUserName +":" +mPassC; 
    String authEncoded = new String(Base64.encodeBase64(up.getBytes())); 
    String authHeader = "Basic " +authEncoded; 
    Map<String, String> headers = new HashMap<String, String>(); 
    headers.put("Authorization", authHeader); 
    mWebView.loadUrl("https://myhost.com/secured_area", headers); 
} 

Questa si avvale del metodo WebView.loadUrl (String url, Map<String, String> additionalHttpHeaders) e per questo esempio sto usando il Base64Encoder da Apache Commons. La parte Base64Encoder è piuttosto banale e se non si desidera includere librerie esterne nell'applicazione (per qualsiasi motivo), è sempre possibile scrivere il proprio own (reference).

Si noti inoltre che il summenzionato metodo WebView.loadUrl (String url, Map<String, String> additionalHttpHeaders) è disponibile solo in API 8+. Per riferimento, vedere anche l'articolo di Wikipedia su Basic Authentication (che discute le intestazioni, ecc.).

+0

Ottima soluzione! Nel mio caso, ho implementato il modulo di login automatico del server, quando l'utente non è riconosciuto, quindi la soluzione con webviewclient non funzionava, ma la mappa delle intestazioni funziona bene! Grazie! – Krystian

0

Scenario Alternativo:

Se disposti a scrivere roundabout 10 lines of javascript using jQuery, questo scenario è piuttosto semplice.

Inject your javascript code into the webview o nel caso in cui tu stia controllando la pagina html che stai visualizzando, includila lì.

Se è necessario interface back from javascript, è possibile farlo. Per scambi di comandi più pesanti, utilizzare CordovaWebView -Interfaccia che ha un ritardo inferiore a seconda del livello dell'API.