Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
spring-issuemaster opened this issue May 24, 2011 · 6 comments
Assignees
Milestone

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented May 24, 2011

David Parks opened SPR-8367 and commented

Reference JIRA: https://jira.springsource.org/browse/SPR-6180?focusedCommentId=66682#comment-66682

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):

http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html#d4e1023

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

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented May 24, 2011

David Parks commented

Incidentally, I just realized how simple this is with 3.x:

HttpClient client = new HttpClient();
client.getParams().setAuthenticationPreemptive(true);
Credentials defaultcreds = new UsernamePasswordCredentials("username", "password");
client.getState().setCredentials(new AuthScope("www.host.com", 443, AuthScope.ANY_REALM), defaultcreds);
RestTemplate restTemplate = new RestTemplate(new CommonsClientHttpRequestFactory(client));

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.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jun 14, 2011

Arjen Poutsma commented

@David,

I feel your pain, but it is a bit unclear to me what exactly do you want us to do?

Do you want to be able to set a HttpContext as a property of the HttpComponentsClientHttpRequestFactory?

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jun 14, 2011

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)

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 13, 2011

Oleg Kalnichevski commented

@David,

It seems like Commons HTTP 4 went just a tad bit abstraction happy and made things a bit more difficult because of it.

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.

@Arjen

Do you want to be able to set a HttpContext as a property of the HttpComponentsClientHttpRequestFactory?

A setter for AuthCache should be sufficient as long as HttpComponentsClientHttpRequestFactory sticks it into the local HTTP context prior to execution of the request.

Oleg

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Dec 6, 2011

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.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Feb 20, 2012

Eugen Paraschiv commented

Hi,
I'm trying to figure out how to use the new infrastructure (with most examples I could find targeting the old one). I'm doing something along the lines of:
DefaultHttpClient newHttpClient = new DefaultHttpClient();
Credentials creds = new UsernamePasswordCredentials( username, password );
newHttpClient.getCredentialsProvider().setCredentials( new AuthScope( host, port, AuthScope.ANY_REALM ), creds );
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory( newHttpClient );
restTemplate.setRequestFactory( requestFactory );

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?
Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.