Я использую HttpClient 4.5.x для вызова SOAP веб-службы с аутентификацией NTLM. Аутентификация проходит успешно. Это трехстороннее рукопожатие. Например, если я делаю пост-запрос, включающий изображения или другое содержимое данных, то для каждого запроса рукопожатия данные отправляются.
Одна рекомендация из онлайн-материала HttpClients - сначала сделать дешевый запрос и использовать тот же объект контекста клиента для последующего запроса большого размера. Это также сказано в документации - Начиная с версии 4.1, HttpClient автоматически кэширует информацию о хостах, которые он успешно аутентифицировал.
Я пробовал то же самое. У меня оба эти запроса впоследствии происходят в том же методе, и в том же потоке. Кэширование (по умолчанию) не происходит. Оба раза происходило трехстороннее рукопожатие.
В журнале я вижу следующее утверждение [org.apache.http.client.protocol.RequestAuthCache] Auth cache not set in the context
Возможно, это значение по умолчанию не работает для NTLM. Есть ли флаг для включения кеширования? Или я должен создать AuthCache самостоятельно и поддерживать? Похоже, только для упреждающей аутентификации, создается кеш аутентификации. Поэтому я сомневаюсь, если это относится к моему делу.
private void callServiceWithAuthentication (ByteArrayEntity entity)
{
try {
/*
AuthScope authScope = new AuthScope("WEBSERVICE-HOST", 443, AuthScope.ANY_REALM, "ntlm");
*/
CloseableHttpClient httpclient = HttpClients.createDefault();
NTCredentials ntCredentials = new NTCredentials(this.userName, this.password, null, "DOMAIN");
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, ntCredentials);
httpClientContext = HttpClientContext.create();
httpClientContext.setCredentialsProvider(credentialsProvider);
HttpHost targetHost = new HttpHost ("WEBSERVICE_HOST", 443);
// First cheap-cost request
HttpGet httpGet = new HttpGet ("WEBSERVICE_URL");
CloseableHttpResponse httpResponse = httpclient.execute(httpGet, httpClientContext);
HttpEntity getResponseEntity = httpResponse.getEntity();
// Following real costly post request
HttpPost post = new HttpPost("WEBSERVICE_URL");
post.setEntity(entity);
// Execute request
try {
CloseableHttpResponse response = httpclient.execute(post, httpClientContext);
StatusLine statusLine = response.getStatusLine();
HttpEntity rentity = response.getEntity();
System.out.println ("HTTP Response Code: " + statusLine.getStatusCode());
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(
statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
if (entity == null) {
throw new ClientProtocolException("Response contains no content");
}
System.out.println (rentity.getContent());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
// Release current connection to the connection pool once you are done
post.releaseConnection();
}
}
catch (Exception e) {e.printStackTrace();}
finally {
}
}