Подтвердить что ты не робот

HTTPClient отправляет два запроса при использовании Basic Auth?

Я использую HTTPClient версии 4.1.2, чтобы попытаться получить доступ к REST через HTTP API, для которого требуется базовая аутентификация. Вот код клиента:

DefaultHttpClient httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager());
// Enable HTTP Basic Auth
httpClient.getCredentialsProvider().setCredentials(
    new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), 
    new UsernamePasswordCredentials(this.username, this.password));

HttpHost proxy = new HttpHost(this.proxyURI.getHost(), this.proxyURI.getPort());

httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);

Когда я создаю запрос POST, например:

HttpPost request = new HttpPost("http://my/url");
request.addHeader(new BasicHeader("Content-type", "application/atom+xml; type=entry")); // required by vendor
request.setEntity(new StringEntity("My content"));

HttpResponse response = client.execute(request);

Я вижу в Charles Proxy, что отправляется два запроса. Один без заголовка Authorization: Basic ... и один с. Первый из них не работает с 401, как и следовало ожидать, но второй проходит очень хорошо с 201.

Кто-нибудь знает, почему это происходит? Спасибо!

EDIT:

Я должен четко указать, что я уже рассмотрел этот вопрос, но, как вы можете видеть, я установил AuthScope таким же образом и не решил моя проблема. Кроме того, я создаю новый HttpClient каждый раз, когда я делал запрос (хотя я использую тот же ConnectionManager), но даже если я использую один и тот же HttpClient для нескольких запросов, проблема все еще сохраняется.

ИЗМЕНИТЬ 2:

Итак, похоже, что предлагал @LastCoder - это способ сделать. См. этот ответ на другой вопрос. Проблема связана с моей нехваткой знаний по спецификации HTTP. То, что я хочу сделать, называется "превентивная аутентификация", а HttpClient docs упоминает об этом здесь. К счастью, ответ, связанный с выше, является гораздо более коротким и чистым способом сделать это.

4b9b3361

Ответ 1

Вместо использования .setCredentials() почему бы вам просто не закодировать USERNAME: PASSWORD и добавить заголовок аутентификации с .addHeader()

Ответ 2

Это означает, что конечная точка сервера/цели создает новый сеанс для каждого запроса клиента. Это заставляет каждую вашу просьбу пройти через дрожание рук, а это означает, что клиенты сначала делают вызов и понимают, что ему требуется авторизация, а затем следует с авторизацией. Что вам нужно сделать, так это отправить авторизацию следующим образом:

httpClient.getParams() setAuthenticationPreemptive (истина);.

Чтобы понять процесс, вы можете регистрировать заголовки своих запросов клиентов, чтобы дать вам представление о том, что ваш клиент отправляет и получает: Посмотрите, работает ли это.