Secure Jersey 2 Hello World Example

Secure Jersey 2 Hello World Example

Jersey is very popular framework to build restful services. In this tutorial, we will learn how to do HTTP basic authentication, so that user won’t be able to access any resource untill they provided the correct username and passowrd. This example has been extended from our previous simple Jersy 2 Hello World tutorial. Please refer the previous tutorial for technology used and basic configurations.

Step1: Intercept the request

Add below servlet configuration in your web.xml file –

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>RESTful Jersey Hello World</display-name>
  <servlet>
       <servlet-name>jersey-serlvet</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.test.rest</param-value>
       </init-param>
       <load-on-startup>1</load-on-startup>
   </servlet>
  
   <servlet-mapping>
       <servlet-name>jersey-serlvet</servlet-name>
       <url-pattern>/rest/*</url-pattern>
   </servlet-mapping>
   
   <filter>
       <filter-name>AuthenticationFilter</filter-name>
       <filter-class>com.test.rest.RestAuthenticationFilter</filter-class>
   </filter>
   <filter-mapping>
    <filter-name>AuthenticationFilter</filter-name>
    <url-pattern>/rest/*</url-pattern>
  </filter-mapping>
   
</web-app>

We have added a servlet filter class RestAuthenticationFilter for all urls of the form /rest/*.

Step 2: RestAuthenticationFilter class

This is basic class to get the HTTP Header value for Authorization.

package com.test.rest;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RestAuthenticationFilter implements javax.servlet.Filter{
	public static final String AUTHENTICATION_HEADER = "Authorization";

	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	public void doFilter(ServletRequest request, ServletResponse response,FilterChain filter) throws IOException, ServletException {
		// TODO Auto-generated method stub
		if (request instanceof HttpServletRequest) {
			HttpServletRequest httpServletRequest = (HttpServletRequest) request;
			String authCredentials = httpServletRequest.getHeader(AUTHENTICATION_HEADER);

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

			boolean authenticationStatus = authenticationService.authenticate(authCredentials);

			if (authenticationStatus) {
				filter.doFilter(request, response);
			} else {
				if (response instanceof HttpServletResponse) {
					HttpServletResponse httpServletResponse = (HttpServletResponse) response;
					httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
				}
			}
		}
		
	}

	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
		
	}
}

Step 3: AuthenticationService

This class is used to authenticate the username and password to verify the user.

package com.test.rest;

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;
	}

}

Step 5: HelloJerset class

package com.test.rest;

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

@Path("/hello")
public class HelloJersey {
	
	@GET
	@Produces(MediaType.TEXT_PLAIN)
	public String sayHello() {
		return "Hello World";
	}
	
	@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> ";
	}
}

Step 6: Run the application

Run the application on any of web application server, I have used tomcat 7 and hit http://localhost:8080/RestExample/rest/hello using Postman a Chrome extension to test the RESTful services.

Hit the above url without any username and password –

securerest-error

We can see, it gives an error 401 Unauthorized which is highlighted in above snapshot

Now add the username and passowrd in the request and again hit the url –
securerest-addusernamepass

Select Basic Auth from Type drop down, provide the username & password and click on Update Request. Now click on Send button and get the result.

securerest-success

 

Download the sample code – RestExample

Stay tuned with us for more tutorials!

Happy Learning!!!

 

Leave a Reply

Your email address will not be published. Required fields are marked *