He estado utilizando HTTPClient versión 4.1.2 para tratar de acceder a un REST a través de HTTP API que requiere autenticación básica. Aquí está el código de cliente:¿HTTPClient envía dos solicitudes cuando se usa autenticación básica?
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);
Cuando construyo una solicitud POST
, así:
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);
que veo en Charles Proxy que hay dos peticiones que se envían. Uno sin el encabezado Authorization: Basic ...
y otro con. El primero falla con un 401, como era de esperar, pero el segundo pasa muy bien con un 201.
¿Alguien sabe por qué sucede esto? ¡Gracias!
EDIT:
Quiero dejar en claro que ya he mirado this question, pero como se puede ver que establezca el AuthScope
la misma manera y no resolvió mi problema. Además, estoy creando un nuevo HttpClient
cada vez que hice una solicitud (aunque utilizo el mismo ConnectionManager
), pero incluso si uso el mismo HttpClient
para múltiples solicitudes, el problema aún persiste.
EDIT 2:
Así que parece que lo @LastCoder estaba sugiriendo es la manera de hacerlo. Vea this answer a otra pregunta. El problema proviene de mi falta de conocimiento sobre las especificaciones HTTP. Lo que estoy buscando hacer es llamar "autenticación preventiva" y HttpClient
docs mention it here. Afortunadamente, la respuesta vinculada a lo anterior es una manera mucho más corta y limpia de hacerlo.
Noté que sucedía lo mismo cuando se usa soap-ui aunque se especificaron las credenciales. – Harindaka
Me pregunto si esto es realmente un comportamiento normal. El cliente realiza una solicitud http sin asumir ninguna autenticación y luego se le informa (a través del 401) que se necesita autenticación básica. En teoría, la autenticación básica se puede realizar de forma preventiva, pero otros esquemas de autenticación (por ejemplo, resumen) necesitan negociación adicional – seand
@se y usted sabe que realmente lo consideré, pero no sé si eso está integrado en el protocolo HTTP o algo así. – daveslab