Андроид 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);
        }