22

我创建了一个加载 WebView 的应用程序。为了登录,该网站需要基本身份验证。当我尝试通过默认浏览器访问该网站时,我收到一个弹出框,提示我输入我的用户名和密码。

如果我尝试通过我的应用程序访问该网站,我会收到错误 401 并且没有弹出窗口。我想知道是否有人可以帮助我?

4

6 回答 6

37

我认为比 Patrick 描述的更优雅的解决方案是使用onReceivedHttpAuthRequestWebViewClient 的方法,如下所述:http: //www.mail-archive.com/android-developers@googlegroups.com/msg30468.html

@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
    handler.proceed("username", "password");
}
于 2012-01-21T13:59:01.547 回答
13

该网站需要身份验证。

首先你对错误做出反应:

webview.setWebViewClient(new WebViewClient() {
   public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
     if (errorCode == 401) {
         // show alert to enter username and password
         // then when those are entered in the alert,
         //     set it through the setHttpAuthUsernamePassword(...) shown below
         //     and then reload the site
     }
   }
 });

使用此功能设置用户和密码:WebView.setHttpAuthUsernamePassword()

webview.setHttpAuthUsernamePassword(host, realm, username, password);

都是字符串。有关主机和领域含义的更多信息,请参见上面的链接。

在此处找到解决方案:向 WebView 提供一些基本的身份验证凭据?

于 2010-11-19T00:21:54.767 回答
10
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
     handler.proceed("USERNAME", "PASSWORD");
}

我认为它对 WebView 上的 401 错误很有帮助。

于 2014-09-07T08:21:33.223 回答
1

我知道这很旧,但是在此处添加另一种方法(使用 onReceivedHttpAuthRequest)对我不起作用。具体来说,有些网页不会提示用户进行基本身份验证,它们只是重定向到登录屏幕。在我的测试中,Grafana 默认情况下恰好有这种行为。

因此,我使用以下代码添加了一个 HTTP Basic auth 标头:

HashMap<String, String> headers = new HashMap<>();
String basicAuthHeader = android.util.Base64.encodeToString((username + ":" + password).getBytes(), android.util.Base64.NO_WRAP);
headers.put("Authorization", "Basic " + basicAuthHeader);
webView.loadUrl(url, headers);

这应该绕过身份验证提示并自动设置凭据。希望这可以帮助寻找另一种解决方案的人。

此外,对于希望使用“https://username:password@url”的 URL 模式的任何人 - 这已被弃用,我认为大多数浏览器会忽略它并丢弃凭据。

编辑

我已经意识到我的上述解决方案仅适用于第一个请求,并且在页面加载后没有后续请求(即对于加载的任何进一步的资源)。

为了使所有后续请求都能正常工作,我必须为 Web 客户端覆盖以下函数:

@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request){
    if (username != null && password != null && username.length() > 0 && password.length() > 0) {
        try {
            OkHttpClient client = new OkHttpClient();
            Request.Builder newRequestBuilder = new Request.Builder()
                    .url(request.getUrl().toString());

            // add headers
            Map<String, String> currentHeaders = request.getRequestHeaders();
            for (String header : currentHeaders.keySet()){
                newRequestBuilder.addHeader(header, currentHeaders.get(header));
            }
            String basicAuthHeader = android.util.Base64.encodeToString((username + ":" + password).getBytes(), android.util.Base64.NO_WRAP);
            newRequestBuilder.addHeader("Authorization", "Basic "+basicAuthHeader);

            //make request
            Request newRequest = newRequestBuilder.build();
            Response response = client.newCall(newRequest).execute();

            // respond with content
            return new WebResourceResponse(response.header("content-type"), response.header("content-encoding", "utf-8"), response.body().byteStream());
        } catch (Exception e) {
            // if an exception occurs, just make a default request
            return null;
        }
    } else {
        // if no username and password, then make a default request
        return null;
    }
}

不幸的是,这段代码不会拦截 POST 请求,只会拦截 GET 请求,这限制了你可以用它做什么。

此外,上面的代码应该添加一些逻辑,以在附加授权标头之前验证初始请求的域与拦截请求的域匹配。否则,授权标头将与所有可能无意将其发送到不同域的请求一起发送(例如,从 CDN 加载资源)。

于 2020-11-17T13:53:42.577 回答
1

这对我有用添加用户名/通过 WebViewClient 然后 setWebViewClient

webView.setWebViewClient(new MyWebViewClient ());

//add this class in main activity 
class MyWebViewClient extends WebViewClient {
    @Override
    public void onReceivedHttpAuthRequest(WebView view,
                                          HttpAuthHandler handler, String host, String realm) {

        handler.proceed("your username", "your password");

    }
}
于 2021-05-27T13:01:23.630 回答
0

使用这个函数onReceivedHttpAuthRequest。它通知主机应用程序 WebView 收到了 HTTP 身份验证请求。宿主应用程序可以使用提供的HttpAuthHandler来设置 WebView 对请求的响应。默认行为是取消请求。

下面是用Kotlin编写的示例

 override fun onReceivedHttpAuthRequest(
            view: WebView,
            handler: HttpAuthHandler,
            host: String,
            realm: String
        ) {
            handler.proceed("username", "password")
        }

在此处查看文档

于 2020-02-03T14:25:25.697 回答