propiedades - Android Webview con conexión https y autenticación básica. ¿Cómo conseguir que esto funcione?
webview desactivado (3)
He investigado e investigado e investigado esto hasta que me he vuelto gris y calvo. ¿Cómo puedo conseguir que una vista web funcione para un sitio que necesita autenticación básica http a través de una conexión https en el nivel de API 8+?
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 puede ver, tuve un cliente de vista web (ahora comentado) que reemplaza el método onReceivedHttpAuthRequest que tiene este aspecto
@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);
}
}
Esto se usó sin el webview.setHttpAuthUsernamePassword y funciona bien, excepto que significa que se envían 2 solicitudes al sitio web. 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 a la mitad ¡La cantidad de tráfico (actualmente con un promedio de 49 solicitudes p / m) es el nombre del juego ahora mismo!
Leí que puedo proporcionar las credenciales de forma preventiva mediante el uso de
webview.setHttpAuthUsernamePassword(Config.SERVER_BASE_URL, "Application", email, pwd);
Sin embargo, esto solo da como resultado Http Basic: acceso denegado errores La constante url base del servidor es el nombre de dominio del sitio, es decir, https://example.com (sin la página), la url real es https://example.com/some_pages . No importa si uso la URL completa o el dominio. He comprobado el reino y lo he hecho correctamente y solo he utilizado cadenas vacías que solo me han proporcionado correo electrónico y contraseña. ¿Podría esto ser algo que ver con el hecho de que el sitio está usando https? Mi código parece funcionar bien en mi caja 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 una 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 me puede dar una solución a esto, ¡siempre estaré en deuda con usted! Incluso podría enviarte un KitKat por correo electrónico.
Este ejemplo simple abusa de una página en HttpWatch ya que es más divertido con un ejemplo público.
El recurso en cuestión, https://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?randomgarbage
utiliza autenticación básica sobre HTTPS y se puede cargar sin un fallo de autenticación como este (probado en 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 Gingerbread. No tengo acceso a nada más antiguo que eso, pero se loadUrl(String, Map<String,String>)
en el nivel de API 8, así que no veo por qué no debería funcionar para eso.
Aclaración para el pañal:
Para admitir la autenticación para solicitudes posteriores, debe proporcionar un WebViewClient
y hacer 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;
}
});
Funcionará para la URL https. En este caso, si obtenemos Untrusted_cer, lo ignoraremos.
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 idea del segundo problema.
para manejar la autorización en su sitio, simplemente anule el siguiente método en su webViewClient y agregue un 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);
}