Http Basic Authentication in Java Using Httpclient

Http Basic Authentication in Java using HttpClient?

Ok so this one works. Just in case anybody wants it, here's the version that works for me :)

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;

public class HttpBasicAuth {

public static void main(String[] args) {

try {
URL url = new URL ("http://ip:port/login");
String encoding = Base64.getEncoder().encodeToString(("test1:test1").getBytes(‌"UTF‌​-8"​));

HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty ("Authorization", "Basic " + encoding);
InputStream content = (InputStream)connection.getInputStream();
BufferedReader in =
new BufferedReader (new InputStreamReader (content));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch(Exception e) {
e.printStackTrace();
}

}

}

Http request with basic auth java

Check this. It worked for me.

  try {
String webPage = "http://192.168.1.1";
String name = "admin";
String password = "admin";

String authString = name + ":" + password;
System.out.println("auth string: " + authString);
byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
String authStringEnc = new String(authEncBytes);
System.out.println("Base64 encoded auth string: " + authStringEnc);

URL url = new URL(webPage);
URLConnection urlConnection = url.openConnection();
urlConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
InputStream is = urlConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);

int numCharsRead;
char[] charArray = new char[1024];
StringBuffer sb = new StringBuffer();
while ((numCharsRead = isr.read(charArray)) > 0) {
sb.append(charArray, 0, numCharsRead);
}
String result = sb.toString();

System.out.println("*** BEGIN ***");
System.out.println(result);
System.out.println("*** END ***");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

How to do Preemptive authentication using Java 11 HTTP client?

The HttpClient behaves in the same way than HttpURLConnection in what preemptive authentication is concerned: for basic authentication it will preemptively send the credentials if it finds them in its cache. However, the cache is populated after the first successful request (or more exactly after the response headers indicating that the authentication was successful are parsed).

If this is not satisfactory for you then a possibility is to handle authentication directly in your code by preemptively inserting the Authorization header in your request, and not setting any Authenticator.

Java 11 HttpClient not sending basic authentication

The service I was calling (in this case, Atlassian's Jira Cloud API) supports both Basic and OAuth authentication. I was attempting to use HTTP Basic, but it sends back an auth challenge for OAuth.

As of the current JDK 11, HttpClient does not send Basic credentials until challenged for them with a WWW-Authenticate header from the server. Further, the only type of challenge it understands is for Basic authentication. The relevant JDK code is here (complete with TODO for supporting more than Basic auth) if you'd like to take a look.

In the meantime, my remedy has been to bypass HttpClient's authentication API and to create and send the Basic Authorization header myself:

public static void main(String[] args) {
var client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.build();
var request = HttpRequest.newBuilder()
.uri(new URI("https://service-that-needs-auth.example/"))
.header("Authorization", basicAuth("username", "password"))
.build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
}

private static String basicAuth(String username, String password) {
return "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
}

apache httpclient doesn't set basic authentication credentials

Okay, by default the basic authentication is turned off. However, enabling it is far too complicated (link) . Therefore one can use this code, which works fine:

DefaultHttpClient http = new DefaultHttpClient();
HttpPost post = new HttpPost(strURL);
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(
Configuration.username,
Configuration.developerKey);
post.addHeader( BasicScheme.authenticate(creds,"US-ASCII",false) );
StringEntity entity = new StringEntity( ac.toXMLString() );
entity.setContentType("text/xml");
post.setEntity( entity );
org.apache.http.HttpResponse response = http.execute( post );

HttpClientBuilder basic auth

From the Preemptive Authentication Documentation here:

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

By default, httpclient will not provide credentials preemptively, it will first create a HTTP request without authentication parameters. This is by design, as a security precaution, and as part of the spec. But, this causes issues if you don't retry the connection, or wherever you're connecting to expects you to send authentication details on the first connection. It also causes extra latency to a request, as you need to make multiple calls, and causes 401s to appear in the logs.

The workaround is to use an authentication cache to pretend that you've already connected to the server once. This means you'll only make one HTTP call and won't see a 401 in the logs:

CloseableHttpClient httpclient = HttpClientBuilder.create().build();

HttpHost targetHost = new HttpHost("localhost", 80, "http");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
new UsernamePasswordCredentials("username", "password"));

// 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);

HttpGet httpget = new HttpGet("/");
for (int i = 0; i < 3; i++) {
CloseableHttpResponse response = httpclient.execute(
targetHost, httpget, context);
try {
HttpEntity entity = response.getEntity();

} finally {
response.close();
}
}

Please note: You need to trust the host you're connecting to, and if you're using HTTP, your username and password will be sent in cleartext (well, base64, but that doesn't count).

You should also be using a much more specific Authscope rather than relying on AuthScope .ANY_HOST and AuthScope.ANY_PORT like in your example.

How do i set basic authentication using apache httpClient

Update:

Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("UserName", "P@sw0rd".toCharArray());
}
});

You also need to set other header properties: (example)

response.addHeader("Access-Control-Allow-Methods", "");
response.setHeader("Access-Control-Allow-Origin", "http://podcastpedia.org");
//allows CORS requests only coming from podcastpedia.org

Code to add a basic authentication property to an httpURLConnection

String basic = "Basic " + Base64.encodeToString(("admin:1234").getBytes(), Base64.NO_WRAP);

con.setRequestProperty("Authorization", basic);


Related Topics



Leave a reply



Submit