Android,HttpURLConnection和处理错误的凭据

时间:2011-08-15 02:32:48

标签: android httpurlconnection

我正在执行GET请求:

HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setConnectTimeout(CONNECT_TIMEOUT);
urlConnection.setReadTimeout(READ_TIMEOUT);
urlConnection.connect();

此时凭据已设置为:

Authenticator.setDefault(new Authenticator() {
  protected PasswordAuthentication getPasswordAuthentication() {
     return new PasswordAuthentication(loginNameString, passwordString.toCharArray());
  }
});

当我提供良好的凭证(即用户名和密码)时,一切正常。

提供错误凭据时连接会发生什么变化?例如,如果我故意提供错误的凭据,我会在urlConnection.getResponseCode()我的应用程序最终超时之后立即致电urlConnection.connect(),我必须强制关闭。那是为什么?

**编辑。据我所知,当凭证不好时,HttpURLConnection只是继续尝试连接(即使有限超时)。 (我知道这是因为我在返回之前在Log.v("Authentication", "Calling...");方法中添加了行getPasswordAuthentication()。如果连接失败,我希望连接停止尝试!

3 个答案:

答案 0 :(得分:7)

使用Basic auth,解决方法是:

connection.setRequestProperty("Authorization", "Basic " + Base64.encodeToString((username + ":" + password).getBytes(), Base64.DEFAULT));

使用android.util.Base64包。另请注意,自API 8(Android 2.2)以来encodeToString()方法可用。

此外,http://code.google.com/p/android/issues/detail?id=7058也很重要。

答案 1 :(得分:1)

您可以使用标志解决此问题,并在首次错误身份验证后在身份验证器中返回null

通过这种方式,您的InputStream将引发您之后可以处理的异常。

复制自:https://stackoverflow.com/a/13615011/628713

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

            ...

    }
}

答案 2 :(得分:0)

我发现设置Authorization标头会导致2.3.7响应代码,所以这里是一个经过调整的身份验证器:

public class FixedAuthenticator extends Authenticator {

    private PasswordAuthentication passAuth;

    public FixedAuthenticator(PasswordAuthentication passAuth) {
        this.passAuth = passAuth;
    }

    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        try {
            return passAuth;
        } finally {
            passAuth = null;
        }
    }
}

在连接之前,您需要设置一个新的实例:

...
Authenticator.setDefault(new FixedAuthenticator(passAuth));
connection.connect();

A working example