2012-01-20 21 views
15

He investigado, investigado e investigado esto hasta que me he puesto gris y calvo. ¿Cómo diablos puedo obtener una vista web para trabajar para un sitio que necesita la autenticación básica HTTP sobre una conexión HTTPS en el nivel de la API 8+vista web de Android con conexión https y autenticación básica. ¿Cómo funciona esto?

tengo el siguiente código

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

Como se puede ver que hice tener un cliente de vista web (ahora comentada) que reemplaza el método onReceivedHttpAuthRequest que se parece a este

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

este fue utilizado sin el webview.setHttpAuthUsernamePassword y funciona bien, excepto que significa 2 solicitudes se emiten a la w ebsite: el primero obtiene un 401 y luego el cliente entra en acción con la autorización Esto está bien para una pequeña cantidad de tráfico del sitio web, pero la mitad del tráfico (actualmente promediando 49 solicitudes p/m) es el nombre del juego en este momento !

leí que puedo preventivamente suministrar las credenciales utilizando

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

Sin embargo esto sólo resulta en Http básica: Acceso denegado errores La constante URL base del servidor es el nombre de dominio del sitio web es decir https://example.com (sin la página) la url real es https://example.com/some_pages. No importa si utilizo la URL completa o el dominio. He comprobado el dominio y lo he corregido y he utilizado solo cadenas vacías que proporcionan solo correo electrónico y contraseña. ¿Podría ser esto algo relacionado con el hecho de que el sitio usa https? Mi código parece funcionar bien en mi cuadro de desarrollo sin https, pero eso puede ser una pista falsa.

Las únicas preguntas de desbordamiento de pila que parecen cubrir mis requisitos no tienen respuestas aceptadas y los documentos no son de ayuda que pueda ver.

Ahora tengo una abolladura tan grande en mi cabeza por golpearla contra una pared de ladrillo que estoy pensando en conseguir un sombrero cuadrado.

Por favor, si alguien puede darme la solución a esto, ¡estaré siempre en deuda con usted! Incluso podría enviarle un correo electrónico a un KitKat

+0

I le [esta pregunta y su respuesta aceptada] (http://stackoverflow.com/questions/1968416/how-to-do-http-authentication-in-android) no resuelve su problema ? –

+0

@aaamos, bien podría resolver mi problema, pero ¿cómo lo aplicaría a un WebView? – jamesc

+0

¿Ha intentado descargar la página web con un httppost y luego suministrarla a una vista web? – Warpzit

Respuesta

15

Este ejemplo simple abusa de una página en HttpWatch ya que es más divertido con un ejemplo de trabajo público.

El recurso en cuestión, https://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?randomgarbage utiliza autenticación básica a través de HTTPS y se puede cargar sin error de autenticación como esto (probado con 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) {} 

Esto funciona en ICS y pan de jengibre. No tengo acceso a nada más antiguo que eso, pero loadUrl(String, Map<String,String>) se introdujo en el nivel 8 de la API, por lo que no veo por qué no debería funcionar para eso.

Aclaración de pañal:

para admitir la autenticación de las solicitudes posteriores se suministra una WebViewClient y haga lo siguiente:

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

Gracias por su respuesta, ciertamente funciona, pero me preocupa que las credenciales aparezcan en la url de los navegadores, que no es absolutamente lo que necesito para esta solución particular. Entonces, ¿tengo que saber si hay alguna posibilidad de que las credenciales 'se filtren' de forma tal que el usuario pueda verlas? – jamesc

+1

El mapa es un conjunto de encabezados HTTP que se incluirán en la respuesta; básicamente, engaña al WebView para que incluya el encabezado que se enviaría si se realizó la solicitud fallida inicial y * luego * respondió con credenciales válidas. - entonces no es parte de la URL en absoluto. – Jens

+0

¡Eso es genial! ¿Se puede aplicar lo mismo a un DefaultHTTPClient? – jamesc

1

Se trabajará para https URL.En este caso nos estamos Untrusted_cer entonces vamos a 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(); 
      } 
     } 

    }); 

no tengo ni idea acerca segundo problema

+0

@james: ¿resolviste tu primer problema? – Sameer

+0

Todavía no estoy seguro, estoy probando las cosas y tanto su solución combinada con la solución @Jens parecen ser exactamente lo que necesito, pero estoy luchando con una última cosa. Estoy a punto de agregar un comentario a la respuesta de Jens sobre esto. ¿Cómo dividiría la recompensa entre ustedes dos? – jamesc

+0

@jamesw: voy a decir dámelo :) – Sameer

0

para el manejo de la autorización en su sitio, simplemente anular el siguiente método en su webViewClient y añadir nombre de usuario y contraseña en su controlador.

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