2012-01-20 9 views
15

Mam zbadane i zbadane i zbadane to, aż będę szary i łysy. Jak na ziemi mogę dostać webview pracować dla strony, która potrzebuje podstawowego uwierzytelniania HTTP za pośrednictwem połączenia HTTPS poziomie api 8+Widok strony na Androida z połączeniem https i podstawowym uwierzytelnieniem. Jak to działa?

Mam następujący kod

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

Jak widać zrobiłem posiada klient zobaczyć web (obecnie wykomentowane), który zastępuje metodę onReceivedHttpAuthRequest który wygląda jak ten

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

ten został wykorzystany bez webview.setHttpAuthUsernamePassword i działa dobrze, z wyjątkiem, że to znaczy, 2 wnioski są wydawane W. ebsite - pierwsza dostaje 401, a następnie klienta z materiałem autoryzacyjnym To jest dobre dla niewielkiej ilości ruchu na stronie, ale zmniejszenie ruchu o połowę (obecnie średnia z 49 żądań p/m) jest teraz nazwą gry !

Czytałem, że mogę wstępnie zapobiegawczo dostarczyć poświadczenia za pomocą

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

Jednak to właśnie powoduje Podstawowe HTTP: Odmowa dostępu błędy Stała baza serwer URL to nazwa domeny dla strony tj https://example.com (bez strony) faktyczny adres URL to https://example.com/some_pages. Nie ma znaczenia, czy używam pełnego adresu URL czy domeny. Sprawdziłem królestwo i mam to poprawne i użyłem tylko pustych ciągów zawierających tylko email i hasło. Czy może to mieć coś wspólnego z faktem, że witryna używa https? Mój kod wydaje się działać dobrze na moim dev boxie bez https, ale może to być czerwony śledzia.!

Jedyne pytania dotyczące przepełnienia stosu, które wydają się obejmować moje wymagania, nie zostały zaakceptowane, a dokumenty nie stanowią pomocy, którą mogę zobaczyć.

Mam teraz tak duży wgniecenie w mojej głowie od uderzania nim o ceglaną ścianę, że myślę o zdobyciu kwadratowego kapelusza.

Proszę, jeśli ktoś może dać mi rozwiązanie tego, będę na zawsze w długach! Mogę nawet wysłać Ci wiadomość e-mail KitKat

+0

biorę to [to pytanie, a jego odpowiedź zaakceptowane] (http://stackoverflow.com/questions/1968416/how-to-do-http-authentication-in-android) nie rozwiąże problemu ? –

+0

@Aaamos, To może rozwiązać mój problem, ale jak mam to zastosować do WebView? – jamesc

+0

Czy próbowałeś pobrać stronę za pomocą httppost, a następnie dostarczyć ją do przeglądarki internetowej? – Warpzit

Odpowiedz

15

Ten prosty przykład nadużywa strony pod HttpWatch, ponieważ jest to bardziej zabawne dzięki działającemu publicznie przykładowi.

Zasób w pytaniu https://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?randomgarbage używa podstawowego uwierzytelniania za pośrednictwem protokołu HTTPS i może być ładowany bez awarii uwierzytelniania tak (testowane przy użyciu Android 2.3.7):

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

To działa na ICS i Piernika. Nie masz dostępu do niczego starszego, ale wprowadzono loadUrl(String, Map<String,String>) na poziomie API 8, więc nie widzę powodu, dla którego nie powinno to działać.

Wyjaśnienie dla pieluszkę:

do obsługi uwierzytelniania dla kolejnych żądań podać WebViewClient i wykonaj następujące czynności:

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

Dziękuję za odpowiedź, to na pewno działa, ale obawiam się, że poświadczenia pojawią się w adresie URL przeglądarki, który absolutnie nie jest tym, czego potrzebuję dla tego konkretnego rozwiązania. Więc muszę wiedzieć, czy jest tak, że poświadczenia mogą "przeciekać" w sposób, w jaki użytkownik mógłby je zobaczyć? – jamesc

+1

Mapa to zestaw nagłówków HTTP, które zostaną uwzględnione w odpowiedzi - w zasadzie polega na tym, że WebView uwzględnia nagłówek, który zostanie wysłany, jeśli przeszedłeś z początkowym błędnym żądaniem, a następnie * następnie * odpowiedział poprawnymi poświadczeniami. - więc w ogóle nie jest częścią adresu URL. – Jens

+0

To świetnie! Czy to samo można zastosować do DefaultHTTPClient? – jamesc

1

To będzie pracować dla https URL.W ten czy jesteśmy coraz Untrusted_cer wtedy będziemy go ignorować

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

    }); 

nie mam pojęcia o drugiego problemu

+0

@james: czy rozwiązałeś swój pierwszy problem? – Sameer

+0

Nie jestem jeszcze pewien, testuję różne rzeczy i oba rozwiązania w połączeniu z rozwiązaniem @Jens wydają się być dokładnie tym, czego potrzebuję, ale walczę z jedną ostatnią rzeczą. Właśnie dodam komentarz do odpowiedzi Jensa na ten temat. Jak podzieliłbym nagrodę między was dwoma? – jamesc

+0

@jamesw: powiem, daj mi :) – Sameer

0

do obsługi zezwolenia na swojej stronie, po prostu zastąpić następującą metodę w swojej webViewClient i dodać nazwę użytkownika i hasło w jego treserze.

@Override 
     public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) { 
      handler.proceed(StringUtils.AUTH_NAME,StringUtils.AUTH_PASS); 
     } 
Powiązane problemy