Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Authenticator on a per connection basis?

I'm building an Eclipse plugin that talks to a REST interface which uses Basic Authentication. When the authentication fails I would like to popup my plugin's settings dialog and retry. Normally I could use the static Authenticator.setDefault() to setup an authenticator for all HttpURLConnection's for this, but since I am writing a plugin I don't want to overwrite Eclipse's default Authenticator (org.eclipse.ui.internal.net.auth);

I thought of setting my custom Authenticator before loading and putting Eclipse's default back afterwards, but I imagine this will cause all sorts of race issues with multithreading so I quickly lost that notion.

Google searches yield all sorts of results basically telling me it's not possible:

The Java URLConnection API should have a setAuthenticator(Authenticator) method for making it easier to use this class in multi-threaded context where authentication is required.

Source

If applications contains few third party plugins and each plugin use its own Authenticator what we should do? Each invocation of "Authenticator.setDefault()" method rewrite previously defined Authenticator...

Source

Are there any different approaches that might help me overcome this issue?

like image 764
Martijn Laarman Avatar asked Mar 01 '09 14:03

Martijn Laarman


2 Answers

If it is not possible with HttpURLConnection I would suggest using the httpclient library from Apache.

A quick example:

HttpClient client = new HttpClient();
client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("test","test"));
GetMethod getMethod = new GetMethod("http://www.example.com/mylogin");
client.executeMethod(getMethod);
System.out.println(getMethod.getResponseBodyAsString());
like image 74
Rich Avatar answered Sep 28 '22 05:09

Rich


Another approach would be to perform the basic authentication yourself on the connection.

    final byte[] encodedBytes = Base64.encodeData((username + ':' + new String(password)).getBytes("iso-8859-1"));
    final String encoded = new String(encodedBytes, "iso-8859-1");

    connection.setRequestProperty("Authorization", "Basic " + encoded);

This would also have the advantage of not requiring an unauthenticated request to receive a 401 before providing the credential on a subsequent request. Similar behavior can be leveraged in the apache http-client by requesting preemptive authentication.

like image 43
Brett Okken Avatar answered Sep 28 '22 03:09

Brett Okken