如何在WebView中处理基本身份验证

时间:2010-11-18 23:43:00

标签: android android-webview

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

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

6 个答案:

答案 0 :(得分:28)

我认为比Patrick描述的更优雅的解决方案是使用WebViewClient的onReceivedHttpAuthRequest方法,如下所述: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");
}

答案 1 :(得分:9)

网站需要身份验证。

首先你对错误作出反应:

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

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

此处找到解决方案:Supply some basic auth credentials to a WebView?

答案 2 :(得分:8)

public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
     handler.proceed("USERNAME", "PASSWORD");
}

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

答案 3 :(得分:1)

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

因此,我改为使用以下代码添加了HTTP Basic身份验证标头:

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

这应该绕过auth提示,而只是自动设置凭据。希望这对寻求其他解决方案的人有所帮助。

此外,对于希望使用URL模式“ https:// username:password @ 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请求,这限制了您的处理能力。

此外,在附加Authorization标头之前,上述代码应添加一些逻辑以验证初始请求的域是否与拦截的请求的域匹配。否则,将随所有请求一起发送Authorization标头,这些请求可能会无意地将其发送到其他域(例如,从CDN加载资源)。​​

答案 4 :(得分: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");

    }
}

答案 5 :(得分:0)

使用此功能 onReceivedHttpAuthRequest 。它通知主机应用程序WebView收到HTTP身份验证请求。主机应用程序可以使用提供的 HttpAuthHandler 设置WebView对请求的响应。默认行为是取消请求。

下面是用科特林

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

Check the Documentation here