Я использую библиотеку Jersey Client 2.0 (с транспортным соединителем Apache HttpClient v4.2.5) для использования веб-службы RESTful. Мое приложение должно поддерживать соединения через прокси-сервер с любой аутентификацией Basic, Digest или NTLM. Я добавил поддержку всех этих типов прокси-аутентификации, и, по сути, все работает правильно.
Вот как я добавил поддержку базовой и дайджест-аутентификации прокси:
ClientConfig config = new ClientConfig();
config.property(ApacheClientProperties.PROXY_URI, "http://www.proxy.com:5678");
config.property(ApacheClientProperties.PROXY_USERNAME, "proxy_user");
config.property(ApacheClientProperties.PROXY_PASSWORD, "proxy_password");
ApacheConnector connector = new ApacheConnector(config);
config.connector(connector);
Client client = ClientBuilder.newClient(config);
Кроме того, веб-служба RESTful, к которой я подключаюсь, также требует самой простой проверки подлинности, которую я обрабатываю, используя следующее:
client.register( new HttpBasicAuthFilter("user", "password") );
Однако мое приложение ведет себя не так, как я хочу: кажется, что каждый отдельный HTTP-запрос, который я делаю, приводит к ответу на запрос аутентификации 407 от прокси-сервера. Это проблема по двум причинам:
Если я делаю запрос
POST
илиPUT
(уже успешно прошедший аутентификацию на прокси-сервере в предыдущем запросе) с телом объекта, предоставленнымInputStream
, он считается "неповторяющимся" запросом, поэтому при получении запроса 407 У меня следующее исключение:org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.
Я мог бы обойти эту проблему, буферизовав данные тела объекта из
InputStream
в строку или массив байтов, чтобы запрос был повторяемым в случае получения запроса 407, но это неэффективно и не решает проблему 2.- Необходимость дублировать каждый запрос, сначала запускать запрос 407, а затем повторять с необходимыми дополнительными заголовками HTTP на месте для проверки подлинности прокси, очень неэффективно. Некоторые из моих клиентских операций включают в себя многочисленные HTTP-запросы к веб-службе RESTful, поэтому этот дополнительный трафик и задержки вызывают сожаление.
Я ожидаю, что после первой успешной аутентификации клиента Jersey на прокси-сервере все последующие запросы, сделанные с использованием того же экземпляра Client
, будут автоматически включать в себя необходимый заголовок Proxy-Authorization
, чтобы предотвратить дальнейшие проблемы 407. Это кажется стандартным подходом для HTTP 1.1 согласно этой ссылке:
Прокси-сервер отправляет клиенту заголовок Proxy-Authenticate, содержащий запрос, в ответе 407 (Proxy Authentication Required). Затем клиент повторяет первоначальный запрос, но добавляет заголовок Proxy-Authorization, содержащий учетные данные, соответствующие задаче. После успешной аутентификации прокси клиент обычно отправляет тот же заголовок Proxy-Authorization на прокси с каждым последующим запросом, а не ждет повторного запроса.
Итак, мой вопрос: какие настройки конфигурации мне нужно применить к клиенту Jersey или к базовому транспортному уровню Apache HttpClient, чтобы включить такое поведение? Я видел различные другие сообщения, в которых рекомендовалось добавить заголовок Proxy-Authorization
вручную, но я бы предпочел избегать этого обходного пути, если это возможно. Я также в идеале ищу решение, которое будет работать со всеми тремя типами прокси-аутентификации, которые я использую (Basic, Digest и NTLM).
Если невозможно предотвратить все эти дополнительные проблемы 407, я также хотел бы получить рекомендации по наилучшему подходу при POSTing или PUTing данных из локальных файлов «повторяемым» способом, чтобы предотвратить проблемы, следующие за проблемой аутентификации прокси-сервера 407.