1

What I want: Send a GET request with a preemtive bassic authentication.

The request looks about like this:

<startURL>/app/process?job=doSomething&param=value1,value2

whereas startURL is always a https link depends on the enviroment.

Looks something like this: https://testABC.com https://prodABC.com

startURL is also placed in a properties file as is for the diffrent enviroments.

What I looked into: http://www.baeldung.com/httpclient-4-basic-authentication

http://www.java-tips.org/other-api-tips/httpclient/how-to-use-basic-authentication.html

http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java

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

It all contains a

 HttpHost targetHost = new HttpHost("hostname", portnumber, "scheme");

Which is what I am having trouble with. This method is also the only one that lets you specify the scheme as "https". One issue is, hat I don't know the portnumber. I think (?) I probably could just specify -1 for the default port, to make it work, but even aside that I also don't have the hostname, only the above mentioned startURL. I don't really want to parse this extra each time, while I also don't really want to add another property, just for the hostname.

I digged around and found this snippet, which looks like just what I want:

HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://foo.com/bar");
httpGet.addHeader(BasicScheme.authenticate(
 new UsernamePasswordCredentials("user", "password"),
 "UTF-8", false));

HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity responseEntity = httpResponse.getEntity();

from HTTP requests with basic authentication

It gives the complete request URL and simply adds the basic header and does not need any port specified. Only that this is now deprecated since Version 4.2:

Deprecated. (4.2) Use ContextAwareAuthScheme.authenticate( Credentials, HttpRequest, org.apache.http.protocol.HttpContext)

I couldn't find a single example for this method to return the basic auth header. It also wants a context as a parameter, which above snipped doesn't have. I really have no real clue how this is supposed to be used.

So, what i want to know concretely:

I just want to set up a request with the complete link, that contains all that there is, like:

https://testABC.com/app/process?job=doSomething&param=value1,value2

and just give this as a parameter for a request that does preemptive basic authentication.

Is there any way to do this without digging up the deprecated methods and how does it look like?

3 Answers 3

3

I ran into the same problem as yours.

What worked for me is the following:

UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "12345");

HttpGet get = new HttpGet("https://foo.bar.com/rest");
HttpHost targetHost = new HttpHost("foo.bar.com", 443, "https");
  CredentialsProvider credsProvider = new BasicCredentialsProvider();
  credsProvider.setCredentials(
          new AuthScope(targetHost.getHostName(), targetHost.getPort()),
          creds);
  credsProvider.setCredentials(AuthScope.ANY,creds);

 // Create AuthCache instance
  AuthCache authCache = new BasicAuthCache();
 // Generate BASIC scheme object and add it to the local auth cache
  BasicScheme basicAuth = new BasicScheme();
  authCache.put(targetHost, basicAuth);

 // Add AuthCache to the execution context
  HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
HttpResponse response = client.execute(targetHost, get, context);

And I found this solution on: HttpClientBuilder basic auth

Sign up to request clarification or add additional context in comments.

3 Comments

Would not have helped, because the HttpHost constructor needs the port specified and the hostname. But as mentioned above I only had the startUrl and explicitly wanted to avoid parsing and breaking it down onto these three argument values.
In my case, creating header your way didn't work though I found that the same Authorization header content was set as Base64. For some reason, the Base64 Authorization set by using httpGet.addHeader(BasicScheme.authenticate( new UsernamePasswordCredentials("user", "password"), "UTF-8", false)) worked and not the one set manually which resulted in 401. Anyway setting this should be simpler as in 4.1.x
Tried serval versions from stackoverflow and this post is the only one worked for me.
1

In the end I wound up writing the header manually on my own and sending things with that:

    String header = "Basic ";       
    String headerValue = "username" + ":" + "password";
    String encodedHeaderValue = Base64.encodeBase64String(headerValue.getBytes());      
    String headerBasic =  header + encodedHeaderValue;

    Header authHeader = new BasicHeader("Authorization", headerBasic);
      ArrayList<Header> headers = new ArrayList<Header>();
      headers.add(authHeader);  

    ArrayList<Header> headers = getHttpHeaders();
    HttpClient client = HttpClients.custom().setDefaultHeaders(headers).build();

    HttpUriRequest request = RequestBuilder.get().setUri(uri).build();
    HttpResponse response = client.execute(request);

    int responseCode = response.getStatusLine().getStatusCode();

Comments

0

To remove the deprecated warnings, replace

httpGet.addHeader(BasicScheme.authenticate(
  new UsernamePasswordCredentials("user", "password"),
  "UTF-8", false));

with

httpGet.addHeader(new BasicScheme().authenticate(
  new UsernamePasswordCredentials("user", "password"), 
  httpGet, new BasicHttpContext()));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.