2010-12-27 11 views
13

Ich möchte ein Android-Webview erstellen, das über eine gesicherte HTTPS-Verbindung mit der Verwendung von Anmeldeinformationen eine Verbindung zu einer Website herstellt.Anmeldeinformationen in einem Android Webview mit gesicherter HTTPS-Verbindung festlegen

Erste Schwierigkeit war es, das Zertifikat (privat) zu akzeptieren, es wurde mit this sehr nützliche Post gelöst.

Zweite Schwierigkeit ist, Anmeldeinformationen zu verwenden, fand ich this Post.

(erste Antwort von dparnas), die ziemlich gut damit zu tun scheint, aber es spricht über HTTP Verbindung und nicht HTTPS. Ich habe es versucht, aber es funktioniert nicht, ich erreiche nur die Anmeldeseite ohne Fehlermeldung, nur die normale leere Form.

Hier ist mein Code:

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

Antwort

3

Die WebView-Klasse als nicht so viel Flexibilität bei der Konnektivität bieten die niedrigen Level-Klassen (wie Httppost oder dergleichen) direkt verwenden.

Wenn Sie die Verbindung zum Server vollständig steuern müssen - oder mit komplizierten Berechtigungsszenarien wie diesem umgehen müssen - verwenden Sie die Low-Level-Klassen, rufen Sie die Daten ab und laden und zeigen Sie WebView.loadData() das HTML.

Here ist ein gutes Beispiel zum Laden von Inhalten mit SSL und einem BasicCredentialProvider. Das Ergebnis davon könnte wie oben beschrieben in das WebView geladen werden.

+0

Es sieht nicht so aus, als ob es mehr Antworten geben wird, also werde ich Ihnen das Kopfgeld geben.Kein Punkt, es zu verlieren :) –

+0

"komplizierte Autorisierungsszenarien" hahahahhah, das ist völlig Standard RFC von Jahren, sollte Webview damit umgehen ... – Nappy

+0

während ich stimme es "sollte" - und ich wünschte, es wäre! - webview stellt nur eine bestimmte Teilmenge des Verhaltens zur Verfügung, das die vollständige HTTP-Bibliothek unterstützt ... – elijah

13

Wie es scheint, dass WebView nicht nativ Basic Authentifizierung behandeln, wenn HTTPS verwenden, begann ich mit dem Gedanken der Einstellung des Authorization Header (enthält den codierten Benutzername/Passwort) manuell einstellen.

Hier ist, wie ich denke, das getan werden kann:

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

Dies nutzt die WebView.loadUrl (String url, Map<String, String> additionalHttpHeaders) Verfahren und für dieses Beispiel verwende ich die Base64Encoder von Apache Commons. Der Base64Encoder-Teil ist ziemlich trivial und wenn Sie (aus welchen Gründen auch immer) keine externen Bibliotheken in Ihre Anwendung aufnehmen wollten, könnten Sie immer Ihre own (reference) schreiben.

Beachten Sie auch, dass die oben genannte Methode WebView.loadUrl (String url, Map<String, String> additionalHttpHeaders) nur in API 8+ verfügbar ist. Als Referenz siehe auch den Wikipedia-Artikel unter Basic Authentication (der die Header usw. behandelt).

+0

Tolle Lösung! In meinem Fall habe ich auf dem Server automatische Login-Formular implementiert, wenn Benutzer nicht erkannt wird, so dass die Lösung mit Webviewclient nicht funktionierte, aber Header-Map funktioniert gut! Vielen Dank! – Krystian

0

Alternativszenario:

Wenn bereit roundabout 10 lines of javascript using jQuery zu schreiben, ist dieses Szenario ziemlich einfach.

Inject your javascript code into the webview oder falls Sie die HTML-Seite kontrollieren, die Sie anzeigen, schließen Sie sie dort ein.

Wenn Sie interface back from javascript benötigen, können Sie das tun. Verwenden Sie für schwereren Befehlsaustausch das CordovaWebView -Interface, das je nach API-Level eine geringere Verzögerung aufweist.

Verwandte Themen