Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
3.1.0.M2 update of the RestTemplate for Apache HTTP Components will default to sending 2 requests on authentication and doesn't support HttpContext parameters without significant extention/rewrite [SPR-8367] #13014
Any use cases which require an HttpContext attribute to be set aren't covered in this implementation, and the extensions required make the whole thing so messy as to make using the Rest Template more of a burden than a benefit. Here is the particular case that I've been fussing with today to little avail, setting preemptive authentication (i.e. send basic authentication headers by default rather than performing 2 requests to authenticate):
The problem being that the RestTemplate implementation as it is has no support for setting HttpContext parameters (the template calls the Http.execute(HttpUriRequest) which uses only the non-accessible default HttpContext), there aren't any good ways to set the default context parameters on the HttpClient in 4.x Apache HTTP Components. You end up needing to extend HttpClient to provide for default HttpContext params on the HttpClient object and the whole thing just becomes a spaghetti mess from there making the template more pain than pleasure.
Affects: 3.1 M2
Referenced from: commits f9144ea
3 votes, 7 watchers
David Parks commented
Incidentally, I just realized how simple this is with 3.x:
HttpClient client = new HttpClient();
It seems like Commons HTTP 4 went just a tad bit abstraction happy and made things a bit more difficult because of it.
Anyway, I just want to emphasize that the main use case I'm concerned with here is enabling preemptive authentication. I don't see much sense in not presenting credentials on the first request in context of a REST service.
David Parks commented
That's a fine question indeed Arjen.
Let's see, there's a few things at issue here. One, HttpContext params are more of a runtime thing in the new HTTP Components, it's designed so that you can have different context params per request. Not something that's really logical in the RestTemplate context.
But the meat of this issue is that pre-emptive authentication isn't easily configured (as it was in commons-http-3.0).
One quick-fix solution that I think is reasonable in the case of the RestTemplate would be to just enabled pre-emptive authentication for us in the RestTemplate's usage of http components. It's a natural default in the context of REST services, and I can't see many other likely use cases for the ContextParams.
A bigger, harrier but all encompassing solution: Provide methods within the RestTemplate4CommonsHttp (sorry, forgot the new name) for properly configuring HttpContext params that will be used at request execution time.
A middle of the road solution might be to simply give us access to the HttpContext params that you will ultimately use in the request. This way we can configure pre-emptive authentication (or other context param features) at creation time similar to how we might in 3.0. This solution is slightly muddied because there are some hard coded default params in the default context that need to be duplicated in an odd sort of way (sorry for the fuzzy description, it's been some weeks since I did this and it was about that point that I threw up my hands and went back to 3.0)
Oleg Kalnichevski commented
As far pre-emptive authentication is concerned it used to be a major source of security related issues prior to HttpClient 4.x. People used to turn it on blindly and often ended up sending their corporate credentials to external sites by mistake without fully realising the implications of their action. HttpClient 4.x forces people to do more work, but at the same time it makes them configure pre-emptive selectively and also enables the use of more secure schemes such as DIGEST, not just inherently insecure BASIC.
A setter for AuthCache should be sufficient as long as HttpComponentsClientHttpRequestFactory sticks it into the local HTTP context prior to execution of the request.
Arjen Poutsma commented
I've opted to add a createHttpContext method to HttpComponentsClientHttpRequestFactory, and passing on the created HttpContext (if any) to the request. This seemed more flexible than having just a AuthCache setter, as the context can contain more than just a authentication cache.
Eugen Paraschiv commented
but the Authentication headers do not seem to be in the request. Is there a working example of configuring RestTemplate with HttpClient (4.x) and Digest Auth?