Hi,
I maintain a Jersey-based library for communicating with a RESTful web
service that requires Basic HTTP authentication. This library must
support communicating through an HTTP proxy server which itself requires
either Basic, Digest or NTLM authentication. The library was previously
working well with Jersey v2.0 except in the case of POST-ing or PUT-ing
data to the web service via an authenticating proxy server, when I would
get the following Exception:
org.apache.http.client.NonRepeatableRequestException: Cannot retry
request with a non-repeatable request entity.
The background to this issue is captured in a currently unanswered
StackOverflow question:
http://stackoverflow.com/questions/19681965/reuse-authorization-header-to-prevent-multiple-407-proxy-authentication-challeng
I was hoping the resolutions to the following Jersey issues in v2.5
would help me in this regard as I could buffer my outgoing requests and
make them "repeatable" in case of any authentication challenges:
https://java.net/jira/browse/JERSEY-2128
https://java.net/jira/browse/JERSEY-2224
I have therefore just upgraded my project to use Jersey v2.5 with Jersey
Apache Connector v2.5 and Apache HttpClient v4.3.1. I am now seeing some
problems when connecting to the RESTful service via a proxy server that
requires Basic authentication. I am wondering whether I am simply not
using the new Jersey v2.5 API correctly, or if there is an underlying
issue here.
The fundamental problem seems to be that Jersey will not include *both*
the required 'Proxy-Authorization' and 'Authorization' HTTP headers at
the same time.
Here is the series of events I am currently observing with a basic HEAD
request using Jersey v2.5:
====
1) Request to RESTful service via proxy server.
2) 407 challenge from proxy server.
3) Repeat original request with additional 'Proxy-Authorization' header.
4) 401 challenge from RESTful service (via proxy).
5) Repeat original request with 'Authorization' header (but without
previously included 'Proxy-Authorization' header).
6) 407 challenge from proxy server.
7) Jersey request finishes with final outcome of 407.
====
Here is the series of events that I expect to happen using Jersey v2.5
in non-preemptive authentication mode, based on my previous experiences
with Jersey v2.0:
====
1) Request to RESTful service via proxy server.
2) 407 challenge from proxy server.
3) Repeat original request with additional 'Proxy-Authorization' header.
4) 401 challenge from RESTful service (via proxy).
5) Repeat original request with additional 'Authorization' header (as
well as 'Proxy-Authorization' header).
6) Success - correct response from RESTful service (via proxy).
====
Here is a simplified representation of the old code I used in Jersey v2.0:
====
final ClientConfig config = new ClientConfig();
config.property(ApacheClientProperties.PROXY_URI,
"
http://www.proxy.com:9999");
config.property(ApacheClientProperties.PROXY_USERNAME, "proxyuser");
config.property(ApacheClientProperties.PROXY_PASSWORD, "proxypassword");
final ApacheConnector connector = new ApacheConnector(config);
config.connector(connector);
final Client client = ClientBuilder.newClient(config);
client.register( new HttpBasicAuthFilter("user", "password") );
====
And here is a simplified representation of the new Jersey v2.5 code:
====
final ClientConfig config = new ClientConfig();
config.property(ClientProperties.PROXY_URI, "
http://www.proxy.com:9999");
config.property(ClientProperties.PROXY_USERNAME, "proxyuser");
config.property(ClientProperties.PROXY_PASSWORD, "proxypassword");
config.connectorProvider( new ApacheConnectorProvider() );
final Client client = ClientBuilder.newClient(config);
final HttpAuthenticationFeature authFeature = HttpAuthenticationFeature
.basicBuilder()
.nonPreemptive()
.credentials("user", "password")
.build();
client.register(authFeature);
====
I have experimented with different values for the following
configuration properties, but I cannot find a combination that fixes the
problem:
====
ApacheClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION
ClientProperties.REQUEST_ENTITY_PROCESSING
====
I have also tried using a pre-emptive basic 'HttpAuthenticationFeature'
instead, but again this does not actually resolve my problem.
Please can somebody let me know if I need to change anything or add
anything to make this work properly in Jersey v2.5?
Thanks very much,
Ian