Андроид webview с подключением https и базовым auth. Как это сделать?
Я исследовал, исследовал и исследовал это, пока не стал серым и лысым.
Как я могу получить webview для работы на сайте, которому требуется HTTP-аутентификация по https-соединению на уровне api 8 +
У меня есть следующий код
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);
Как вы можете видеть, у меня был клиент веб-представления (теперь прокомментирован), который переопределяет метод onReceivedHttpAuthRequest, который выглядит как этот
@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);
}
}
Это использовалось без webview.setHttpAuthUsernamePassword и отлично работает, за исключением того, что это означает, что на сайт выдается 2 запроса. Первый получает 401, а затем клиент использует материал авторизации. Это нормально для небольшого количества веб-сайта трафик, но вдвое сокращает объем трафика (в настоящее время составляет в среднем 49 запросов p/m) - это название игры прямо сейчас!
Я прочитал, что я могу предварительно предоставить учетные данные, используя
webview.setHttpAuthUsernamePassword(Config.SERVER_BASE_URL, "Application", email, pwd);
Однако это просто приводит к Http Basic: Access denied errors
Постоянная URL-адрес базы сервера - это доменное имя для сайта, то есть https://example.com (без страницы) фактический URL-адрес https://example.com/some_pages.
Не имеет значения, использую ли я полный URL-адрес или домен. Я проверил область, и у меня это правильно, и я использовал только пустые строки, содержащие только электронную почту и пароль.
Может ли это быть связано с тем, что сайт использует https? Мой код, похоже, отлично работает в моей dev-блоке без https, но это может быть красная селедка.!
Единственные проблемы с переполнением стека, которые, похоже, соответствуют моим требованиям, не получили принятых ответов, и документы не помогают мне видеть.
У меня теперь есть такая большая вмятина в голове, ударяя ее о кирпичную стену, о которой я думаю о том, чтобы получить квадратную шляпу.
Пожалуйста, если кто-нибудь может дать мне решение этого, я буду навсегда в вашем долге!
Я мог бы даже отправить вам по электронной почте KitKat
Ответы
Ответ 1
Этот простой пример злоупотребляет страницей HttpWatch, так как это более интересно с рабочим публичным примером.
В рассматриваемом ресурсе https://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?randomgarbage
используется базовый auth over HTTPS и может быть загружен без проверки подлинности (например, с помощью 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) {}
Это работает на ICS и Gingerbread. У вас нет доступа к чему-либо более старшему, но loadUrl(String, Map<String,String>)
был представлен в уровне API 8, поэтому я не понимаю, почему он не должен работать для этого.
Уточнение для подгузника:
Чтобы поддерживать аутентификацию для последующих запросов, вы предоставляете WebViewClient
и делаете следующее:
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url, <your map containing the Authorization header>);
return true;
}
});
Ответ 2
Он будет работать для https-URL. В этом случае, если мы получим Untrusted_cer, мы будем игнорировать его
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();
}
}
});
Я понятия не имею о второй проблеме
Ответ 3
для обработки авторизации на вашем сайте, просто переопределите следующий метод в своем webViewClient и добавьте имя пользователя и пароль в его обработчик.
@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
handler.proceed(StringUtils.AUTH_NAME,StringUtils.AUTH_PASS);
}