HTTP-клиент 4.x Кеш аутентификации не установлен в контексте - PullRequest
0 голосов
/ 26 февраля 2020

Я использую 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 {
        }
    }

1 Ответ

0 голосов
/ 26 февраля 2020

Я должен был получить первый ответный объект перед вторым запросом. Затем второй запрос больше не выполнял аутентификацию (трехстороннее рукопожатие).

EntityUtils.consume(getResponseEntity);

Мне нужно выполнить дополнительную очистку

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...