Adam Bien's Weblog

Client-Side HTTP Basic Access Authentication With JAX-RS 2.0

Basic Access Authentication is easy to implement with JAX-RS 2.0 and a ClientRequestFilter realization:


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.core.MultivaluedMap;
import javax.xml.bind.DatatypeConverter;

public class Authenticator implements ClientRequestFilter {

    private final String user;
    private final String password;

    public Authenticator(String user, String password) {
        this.user = user;
        this.password = password;
    }

    public void filter(ClientRequestContext requestContext) throws IOException {
        MultivaluedMap<String, Object> headers = requestContext.getHeaders();
        final String basicAuthentication = getBasicAuthentication();
        headers.add("Authorization", basicAuthentication);

    }

    private String getBasicAuthentication() {
        String token = this.user + ":" + this.password;
        try {
            return "BASIC " + DatatypeConverter.printBase64Binary(token.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException ex) {
            throw new IllegalStateException("Cannot encode with UTF-8", ex);
        }
    }
}

A filter instance can be registered during the creation of the client:


import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;

Client client = ClientBuilder.newClient().register(new Authenticator(user, password));
... = this.client.target(uri);


…and the authentication becomes transparent…

The code above was borrowed from the https://github.com/AdamBien/e2ftp project.

See you at Java EE Workshops at MUC Airport!


NEW dates, new workshop: Java EE 7 Workshops: Bootstrap, Effective, Architectures, JavaScript Bootstrap and HTML 5 December, 7th-11th
NEW: Effective Java EE 7 -- Available For Streaming

Newsletter: airhacksnews.com

A book about rethinking Java EE Patterns

Comments:

Would this be possible to use if the client is only written in javascript? Any example of this?

Best regards
Marthin

Posted by Marthin on September 03, 2013 at 12:38 PM CEST #

Excellent. Works as mentioned. Thanks

Posted by sarab on March 24, 2014 at 09:58 PM CET #

Thanks Adam, it was big help as always.

Posted by Marcin on March 25, 2014 at 11:16 PM CET #

For me it's working only after replacing BASIC to Basic

Posted by Tomek on April 04, 2014 at 02:19 PM CEST #

If anyone need to hit a service behind form autehtication.

Used just like the Authenticator.

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response;

public class FormAuthenticator implements ClientRequestFilter {

private ArrayList<Object> cookies;

public FormAuthenticator(String baseUri, String username, String password) {

cookies = new ArrayList<>();

Client client = ClientBuilder.newClient();

WebTarget baseTarget = client.target(baseUri);

Form form = new Form();
form.param("j_username", username);
form.param("j_password", password);
Response response = baseTarget.path("j_security_check")
.request("application/x-www-form-urlencoded")
.post(Entity.form(form));

Map<String, NewCookie> cr = response.getCookies();

for (NewCookie cookie : cr.values()) {
cookies.add(cookie.toCookie());
}
}

public void filter(ClientRequestContext requestContext) throws IOException {
if (cookies != null) {
requestContext.getHeaders().put("Cookie", cookies);
}
}
}

// Michael - @jarry_dk

Posted by Michael Bornholdt Nielsen on April 10, 2014 at 10:31 AM CEST #

Hi Adam,

initially thanks for the code. It was a big help. The scenario I used the code for, was communication between two JBoss applications.
Last month we updated the version (to Wildfly) of the JBoss running the Webservice. After the update I got a "401 Unauthorized" error. After long research I found out, that the Authorization-Header has to start with "Basic" and not "BASIC", otherwise the JBoss rejects the connection with mentioned error.

Posted by Georg Henkel on July 29, 2014 at 02:36 PM CEST #

HI adam
i want to perform the token based authentication,
so how can we do that using clientRequestFilter

Posted by Swapnil Dewanagan on November 14, 2014 at 10:32 AM CET #

hi adam

this authentication came under Basic authentication.

But if i want to perform it using bearer authentication scheme then how can we do it?

Posted by swapnil dewangan on November 17, 2014 at 06:31 AM CET #

Hi Adam,

I used your code here:

https://github.com/fragkakis/tx-loader/blob/master/src/main/java/org/fragkakis/txclient/util/Authenticator.java

The project is licensed under Apache 2.

Is this OK?

Thanks,

Markos

Posted by Markos Fragkakis on December 22, 2014 at 10:58 PM CET #

@Markos,

absolutely!

Thanks for using my stuff.

It would be nice, if you could link back to my github repo from your README.md,

thanks,

adam

Posted by Adam Bien on January 11, 2015 at 08:17 AM CET #

Hi,

Is there something similar for JAX-RS 1.1?

Thank you!

Posted by Armando Flores on January 28, 2015 at 01:17 AM CET #

I've worked in spring. I'm learning JAX-RS Jersey now. Wierd thing I'm noticing is I cant tell my server on which page should I redirect the user to. Assume I've click on a basic page which shows list of countries, after making authentication with the server, how can I show "Country List" for the client..? In spring I'm doing like return "admin/countryList"; , but how can I do it in jax-rs? will automatically fetch that page if the response status is 200?

Posted by Naveen Kumar on February 22, 2015 at 05:50 PM CET #

It is very important to have "Basic" and not "BASIC" in the "Authorization " header field.

Posted by Andrei on April 27, 2015 at 10:40 AM CEST #

Hi Adam,

I'm using JAX-RS 1.1 and looking for a convenience way to secure a restful application

Thx

Marc

Posted by Marc Nguidjol on May 11, 2015 at 02:18 PM CEST #

Hi Adam,

I am not very good with jax-rs. I am using this Authenticator with your utility "loadr" for doing deploy to a remote glassfish with username and password. It is not working. Can you help ?

Posted by Bruno on August 27, 2015 at 11:50 AM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
realworldpatterns.com
Online Workshops
...the last 150 posts
...the last 10 comments
License