我正在执行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()
。如果连接失败,我希望连接停止尝试!
答案 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();