【问题标题】:android webview with https connection and basic auth. How to get this working?带有 https 连接和基本身份验证的 android webview。如何让这个工作?
【发布时间】:2012-01-20 00:59:13
【问题描述】:

我一直在研究、研究和研究这个,直到我变得灰白秃顶。 对于需要通过 api 级别 8+ 上的 https 连接进行 http 基本身份验证的站点,我到底如何获得 webview 工作

我有以下代码

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

如您所见,我确实有一个 Web 视图客户端(现已注释掉),它覆盖了如下所示的 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 个请求)是现在的游戏名称!

我读到我可以通过使用预先提供凭据

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

但这只会导致 Http Basic: Access denied 错误 服务器基本 url 常量是站点的域名,即 https://example.com(没有页面)实际 url 是 https://example.com/some_pages。 无论我使用完整的 url 还是域,都没有区别。我已经检查了领域并且我有正确的并且我只使用了只提供电子邮件和密码的空字符串。 这可能与该网站使用 https 的事实有关吗?我的代码在没有 https 的情况下在我的开发盒上似乎可以正常工作,但这可能是一个红鲱鱼。!

似乎满足我的要求的唯一堆栈溢出问题没有得到接受的答案,而且我看不到文档的帮助。

我现在因为撞到砖墙上而在我的头上留下了这么大的凹痕,我正在考虑买一顶方帽。

如果有人能给我解决这个问题的方法,我将永远欠你的债! 我什至可以通过电子邮件向您发送 KitKat

【问题讨论】:

  • 我认为this question and its accepted answer 不能解决您的问题?
  • @aaamos,它可以很好地解决我的问题,但我如何将它应用到 WebView?
  • 您是否尝试过使用 httppost 下载网页,然后将其提供给 webview?
  • 你不能只做email:password@example.com/some_page并动态构造url吗? (尽管您可能必须对电子邮件进行编码)...这可能是潜在的安全问题,但您可以尝试一下。
  • 为什么要测试 !pwd.equalsIgnoreCase("-1") 两次?

标签: android android-webview


【解决方案1】:

这个简单的示例滥用了HttpWatch 上的一个页面,因为它与一个有效的公共示例相比更有趣。

有问题的资源,@987654322@ 使用基于 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&lt;String,String&gt;) 是在 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;
        }
    });

【讨论】:

  • 感谢您的回答,它确实有效,但我担心凭据会出现在浏览器 url 中,这绝对不是我对这个特定解决方案所需要的。所以我需要知道凭据是否会以用户能够看到的方式“泄漏”?
  • Map 是一组将包含在响应中的 HTTP 标头 - 基本上它会欺骗 WebView 以包含在您处理初始失败请求和 时将发送的标头然后 以有效凭据响应。 - 所以它根本不是 URL 的一部分。
  • 太好了!可以将同样的应用到 DefaultHTTPClient 吗?
  • 也可以使用 DefaultHttpClient 进行抢先式身份验证,例如以与此修复类似的方式询问和回答 here
  • 这对后续请求有何作用?例如填写表格并提交,您也可以在那里“注入”那些身份验证标头吗?否则它只是完整解决方法的一半......
【解决方案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();
            }
        }

    });

我不知道第二个问题

【讨论】:

  • 我还不确定,我正在测试,您的解决方案与@Jens 解决方案相结合似乎正是我所需要的,但我正在努力解决最后一件事。我正要向 Jens 对此的回答添加评论。我将如何在你们两个之间分配赏金?
  • @jamesw: 我会说把它给我 :)
  • 嘿,詹姆斯,我发现了关于抢占式 http 基本授权的讨论。所以看看这个链接,code.google.com/p/android-xmlrpc/issues/detail?id=6
  • 好吧,既然您遇到了抢占式身份验证和 not SSL 证书的问题,我会说这个答案完全不相关;)
  • @Jens:他提到了 https url。我想你没有读清楚。通常它不可能在 webview 中运行 https url。我们必须避免 sslerror
【解决方案3】:

要在您的网站上处理授权,只需在您的 webViewClient 中覆盖以下方法并在其处理程序中添加用户名和密码。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 2019-09-27
    • 2013-03-19
    • 2014-07-05
    相关资源
    最近更新 更多