sUrlConnection与身份验证的基本身份验证永远迭代时的

sUrlConnection与身份验证的基本身份验证永远迭代时的

本文介绍了安卓:HttpsUrlConnection与身份验证的基本身份验证永远迭代时的密码是错误的(在401响应)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我使用的是 HttpsUrlConnection 使用基本身份验证通过使用身份验证键,设置默认身份验证目标:

  Authenticator.setDefault(新的认证(){
    受保护的PasswordAut​​hentication的getPasswordAut​​hentication(){
        返回新的PasswordAut​​hentication(用户,为userpass
            .toCharArray());
    }
});
 

当我进入我的网络服务连接调用我的的getPasswordAut​​hentication()方法来获得证书并将其发送到网络服务器。这工作还好吧,只要密码正确。 :)

然而,它只是碰巧有人更改了基本身份验证密码的网络服务器上,然后我的要求没有返回。

我调试它,什么情况是,我的电话,以的getInputStream()永远不会返回。该 HttpsUrlConnection 确实得到了401响应,并在内部再次得到相同的凭据反应这一点。但是,因为我只提供了一个用户和密码,这将失败一次(又一次...)。

所以我的问题是:(RESP 401响应)?我怎么能prevent这一点,在那里有一个钩子反应到错误的密码,这样我就可以显示相应的错误信息,并取消该请求

下面是被repeatingly呼吁 HttpsUrlConnection 的方法的堆栈跟踪的摘录:

  1:MyOwnHttpConnection $ 3.getPasswordAut​​hentication()线:99
2:Authenticator.requestPasswordAut​​hentication(InetAddress类,整型,字符串,字符串,字符串)线:162
3:HttpsURLConnectionImpl $ HttpsEngine(HttpURLConnectionImpl).getAuthorizationCredentials(字符串)行:1205
4:HttpsURLConnectionImpl $ HttpsEngine(HttpURLConnectionImpl).processAuthHeader(字符串,字符串)线:1178
5:HttpsURLConnectionImpl $ HttpsEngine(HttpURLConnectionImpl).processResponseHeaders()线:1118
6:HttpsURLConnectionImpl $ HttpsEngine(HttpURLConnectionImpl).retrieveResponse()线:1044
7:HttpsURLConnectionImpl $ HttpsEngine(HttpURLConnectionImpl).getInputStream()线:523
8:HttpsURLConnectionImpl.getInputStream()线:283
 

解决方案

我通过抽象的请求/响应逻辑走成 MyRequest 类解决了这个问题。这让我有一个请求范围的变量,可以告诉我的身份验证是否应该使用指定的用户名和密码进行请求,或者它是否应该停止重试(通过返回)。它看起来有点像以下(考虑这个伪code)

 公共类MyRequest
{
    私人布尔alreadyTriedAuthenticating = FALSE;
    私人URL网址;

    ...

    公共无效的send()
    {
        HttpURLConnection的连接=(HttpURLConnection类)url.openConnection();
        Authenticator.setDefault(新的认证(){
            受保护的PasswordAut​​hentication的getPasswordAut​​hentication(){
                如果(!alreadyTriedAuthenticating)
                {
                    alreadyTriedAuthenticating = TRUE;
                    返回新的PasswordAut​​hentication(用户名,password.toCharArray());
                }
                其他
                {
                    返回null;
                }
            }
            InputStream的时间=新的BufferedInputStream(connection.getInputStream());

            ...

    }
}
 

I am using an HttpsUrlConnection with Basic Authentication by using an Authenticator and setting a default Authenticator object like this:

Authenticator.setDefault(new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("user", "userpass"
            .toCharArray());
    }
});

When I access my web-service the connection calls my getPasswordAuthentication() method to get the credentials and sends this to the web-server. This works allright as long as the password is correct. :)

However, it just happened that someone changed the basic authentication password on the web-server and then my request did not return.

I debugged it and what happens is that my call to getInputStream() never returns. The HttpsUrlConnection does get a 401 response and reacts to this internally by getting the same credentials again. But since I only provided one user and password this will fail again (and again...).

So my question is: How can I prevent this and where is there a hook to react to a wrong password (resp. a 401 response) so I can show an appropriate error message and cancel the request?

Here is an extract of the stack trace of the methods that are called repeatingly on HttpsUrlConnection:

1: MyOwnHttpConnection$3.getPasswordAuthentication() line: 99
2: Authenticator.requestPasswordAuthentication(InetAddress, int, String, String, String) line: 162
3: HttpsURLConnectionImpl$HttpsEngine(HttpURLConnectionImpl).getAuthorizationCredentials(String) line: 1205
4: HttpsURLConnectionImpl$HttpsEngine(HttpURLConnectionImpl).processAuthHeader(String, String) line: 1178
5: HttpsURLConnectionImpl$HttpsEngine(HttpURLConnectionImpl).processResponseHeaders() line: 1118
6: HttpsURLConnectionImpl$HttpsEngine(HttpURLConnectionImpl).retrieveResponse() line: 1044
7: HttpsURLConnectionImpl$HttpsEngine(HttpURLConnectionImpl).getInputStream() line: 523
8: HttpsURLConnectionImpl.getInputStream() line: 283
解决方案

I solved this problem by abstracting request/response logic away into a MyRequest class. This allows me to have a request-scoped variable that can tell my Authenticator whether it should make a request using a specified username and password, or whether it should stop retrying (by returning null). It looks somewhat like the following (consider this pseudocode)

public class MyRequest
{
    private boolean alreadyTriedAuthenticating = false;
    private URL url;

    ...

    public void send()
    {
        HttpUrlConnection connection = (HttpUrlConnection) url.openConnection();
        Authenticator.setDefault(new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                if (!alreadyTriedAuthenticating)
                {
                    alreadyTriedAuthenticating = true;
                    return new PasswordAuthentication(username, password.toCharArray());
                }
                else
                {
                    return null;
                }
            }
            InputStream in = new BufferedInputStream(connection.getInputStream());

            ...

    }
}

这篇关于安卓:HttpsUrlConnection与身份验证的基本身份验证永远迭代时的密码是错误的(在401响应)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 23:30