Intercept JAX-RS Request with Jersey ContainerRequestFilter

In this RESTful services tutorial series, we will see about how to intercept a request in JAX-RS restful web service. JAX-RS specification is the Java API for RESTful web services and Jersey is its reference implementation. In the previous tutorial we saw about doing authentication in REST with plain servlet filters.

In this tutorial lets march to the next step. Lets do the HTTP basic authentication for RESTful services using ContainerRequestFilter. It is an interface in the JAX-RS specification.

ContainerRequestFilter

ContainerRequestFilter this is an interface and should be implemented by the container request filters.

RESTful Web Services HTTP Authentication

Let us see the ContainerRequestFilter in action using an example project. I recommend you to go through the previous tutorial RESTful Services HTTP basic Authentication since we will using the same project with the exception of the filter class.

Download

JaxRsFilterAuthentication

package com.javapapers.webservices.rest.jersey;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.Provider;

@Provider
public class JaxRsFilterAuthentication implements ContainerRequestFilter {
	public static final String AUTHENTICATION_HEADER = "Authorization";

	@Override
	public void filter(ContainerRequestContext containerRequest)
			throws WebApplicationException {

		String authCredentials = containerRequest
				.getHeaderString(AUTHENTICATION_HEADER);

		// better injected
		AuthenticationService authenticationService = new AuthenticationService();

		boolean authenticationStatus = authenticationService
				.authenticate(authCredentials);

		if (!authenticationStatus) {
			throw new WebApplicationException(Status.UNAUTHORIZED);
		}

	}
}

RESTful Resource

Just a Hello World service.

package com.javapapers.webservices.rest.jersey;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/helloworld")
public class HelloWorld {

	@GET
	@Produces(MediaType.TEXT_PLAIN)
	public String sayPlainTextHello() {
		return "Hello World RESTful Jersey!";
	}

	@GET
	@Produces(MediaType.TEXT_XML)
	public String sayXMLHello() {
		return "<?xml version=\"1.0\"?>" + "<hello> Hello World RESTful Jersey"
				+ "</hello>";
	}

	@GET
	@Produces(MediaType.TEXT_HTML)
	public String sayHtmlHello() {
		return "<html> " + "<title>" + "Hello World RESTful Jersey"
				+ "</title>" + "<body><h1>" + "Hello World RESTful Jersey"
				+ "</body></h1>" + "</html> ";
	}

}

HTTP Basic Authentication Service

This is a service class that takes care or parsing out the credentials and doing the auth.

package com.javapapers.webservices.rest.jersey;

import java.io.IOException;
import java.util.Base64;
import java.util.StringTokenizer;

public class AuthenticationService {
	public boolean authenticate(String authCredentials) {

		if (null == authCredentials)
			return false;
		// header value format will be "Basic encodedstring" for Basic
		// authentication. Example "Basic YWRtaW46YWRtaW4="
		final String encodedUserPassword = authCredentials.replaceFirst("Basic"
				+ " ", "");
		String usernameAndPassword = null;
		try {
			byte[] decodedBytes = Base64.getDecoder().decode(
					encodedUserPassword);
			usernameAndPassword = new String(decodedBytes, "UTF-8");
		} catch (IOException e) {
			e.printStackTrace();
		}
		final StringTokenizer tokenizer = new StringTokenizer(
				usernameAndPassword, ":");
		final String username = tokenizer.nextToken();
		final String password = tokenizer.nextToken();

		// we have fixed the userid and password as admin
		// call some UserService/LDAP here
		boolean authenticationStatus = "admin".equals(username)
				&& "admin".equals(password);
		return authenticationStatus;
	}
}

Jersey provider package configuration

Remember to map your packages as below for the Jersey Runtime.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>RESTful Jersey Hello World</display-name>

	<servlet>
		<servlet-name>RESTful Jersey Hello World Service</servlet-name>
		<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
		<init-param>
			<param-name>jersey.config.server.provider.packages</param-name>
			<param-value>com.javapapers.webservices.rest.jersey</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>RESTful Jersey Hello World Service</servlet-name>
		<url-pattern>/rest/*</url-pattern>
	</servlet-mapping>

</web-app>

Deploy the RESTful service and invoke the following resource:

http://localhost:8080/RESTful_Jersey_Hello_World/rest/helloworld

JAX-RS-Filter

Download

Download the following JAR files from Jersey download bundle and add to the project lib.

aopalliance-repackaged-2.4.0-b06.jar
asm-debug-all-5.0.2.jar
hk2-api-2.4.0-b06.jar
hk2-locator-2.4.0-b06.jar
hk2-utils-2.4.0-b06.jar
javassist-3.18.1-GA.jar
javax.annotation-api-1.2.jar
javax.inject-2.4.0-b06.jar
javax.servlet-api-3.0.1.jar
javax.ws.rs-api-2.0.1.jar
jaxb-api-2.2.7.jar
jersey-client.jar
jersey-common.jar
jersey-container-servlet-core.jar
jersey-container-servlet.jar
jersey-guava-2.15.jar
jersey-server.jar
org.osgi.core-4.2.0.jar
osgi-resource-locator-1.0.1.jar
persistence-api-1.0.jar
validation-api-1.1.0.Final.jar

This Web Service tutorial was added on 25/02/2015.

Comments on "Intercept JAX-RS Request with Jersey ContainerRequestFilter" Tutorial:

  1. RTM Shanmuganathan says:

    Simply Great!!!

Comments are closed for this "Intercept JAX-RS Request with Jersey ContainerRequestFilter" tutorial.