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 workshop: Microservices with Java EE 7 and Java 8, January 26th, 2015, Airport Munich

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 #

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