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?

Community
  • 1
  • 1
kumoyadori
  • 337
  • 2
  • 10
  • 21

2 Answers2

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

Community
  • 1
  • 1
serverfaces
  • 1,155
  • 4
  • 22
  • 49
  • 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. – kumoyadori Apr 01 '15 at 10:11
  • 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 – serverfaces Apr 01 '15 at 17:00
  • Tried serval versions from stackoverflow and this post is the only one worked for me. – Tatera Sep 07 '18 at 05:06
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();
Prateek
  • 12,014
  • 12
  • 60
  • 81
kumoyadori
  • 337
  • 2
  • 10
  • 21