Android, HttpURLCподключение и обработка неверных учетных данных - PullRequest
4 голосов
/ 15 августа 2011

Я выполняю запрос 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 ]

7 голосов
/ 17 декабря 2011

При базовой аутентификации обходной путь:

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

Использование пакета android.util.Base64.Также обратите внимание, что метод encodeToString() доступен начиная с API 8 (Android 2.2).

Также актуален http://code.google.com/p/android/issues/detail?id=7058.

1 голос
/ 15 января 2014

Вы можете решить эту проблему, используя флаг и возвращая 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());

            ...

    }
}
0 голосов
/ 16 декабря 2012

Я обнаружил, что установка заголовка Authorization приводит к получению кода ответа 400 на 2.3.7, так что вместо этого вот настроенный Authenticator:

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

Рабочий пример .

...