In this tutorial I am going to show you how we can authenticate the REST webservice using sending credential information in Cookie.

The most important concept in REST is resources, which are identified by global IDs — typically using URIs. Client applications use HTTP methods (GET/ POST/ PUT/ DELETE) to manipulate the resource or collection of resources. A RESTful Web service is implemented using HTTP and the principles of REST. Typically, a RESTful Web service should define the following aspects:

The base/root URI for the Web service such as http://<host>/<appcontext/contextpath>/<url pattern>/<resources>.
The MIME type of the response data supported, which are JSON/XML/TEXT/HTML etc.
The set of operations supported by the service. (for example, POST, GET, PUT or DELETE).

Methods

HTTP methods are mapped to CRUD (create, read, update and delete) actions for a resource. Although you can make slight modifications such as making the PUT method to be create or update, the basic patterns are listed as follows.

HTTP GET: Get/List/Retrieve an individual resource or a collection of resources.
HTTP POST: Create a new resource or resources.
HTTP PUT: Update an existing resource or collection of resources.
HTTP DELETE: Delete a resource or collection of resources.

Prerequisites

Eclipse, JDK 1.8, JAX-RS jars 2.6
Have maven installed and configured
JAX-RS dependencies in pom.xml

For this tutorial we will create a web maven project in Eclipse. If you already have an idea on how to create a maven project in Eclipse will be great otherwise I will tell you here how to create a maven project in Eclipse.

Step 1. Create a web maven project in Eclipse

Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.

maven-arctype-webapp

Now enter the required fields (Group Id, Artifact Id) as shown below

Group Id : com.roytuts
Artifact Id : rest-cookie

Step 2. Modify the pom.xml file as shown below.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.roytuts</groupId>
    <artifactId>rest-cookie</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>

    <name>rest-cookie Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jdk.version>1.8</jdk.version>
        <junit.version>4.11</junit.version>
        <jersey.version>2.6</jersey.version>
        <servlet.version>3.1.0</servlet.version>
        <commons-logging.version>1.1.1</commons-logging.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servlet.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.grizzly</groupId>
            <artifactId>grizzly-http-server</artifactId>
            <version>2.3.11</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.bundles.repackaged</groupId>
            <artifactId>jersey-guava</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-grizzly2-http</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
            <artifactId>jersey-test-framework-provider-inmemory</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>${commons-logging.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>rest-cookie</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Step 3. If you see JRE System Library[J2SE-1.4] then change the version by below process

Do right-click on the project and go to Build -> Configure build path, under Libraries tab click on JRE System Library[J2SE-1.4], click on Edit button and select the appropriate jdk 1.8 from the next window. Click on Finish then Ok.

Step 4. Modify web.xml file to use the jersey servlet

<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>rest-cookie</display-name>
    <servlet>
        <servlet-name>REST</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.roytuts.rest.cookie.resources</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- Map /rest/* to Jersey -->
    <servlet-mapping>
        <servlet-name>REST</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

Step 5. Create a REST resource class as shown below

package com.roytuts.rest.cookie.resources;

import java.util.Map;

import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/todo")
public class ToDoResource {

    @Context
    HttpHeaders httpHeaders;

    @GET
    @Path("getToDo/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getToDo(@PathParam("id") @NotNull int id) {
        //read headers information to retrieve cookie
        Map<String, Cookie> cookieMap = httpHeaders.getCookies();
        String userName = cookieMap.get("username").getValue();
        String userPass = cookieMap.get("password").getValue();
        //authenticate
        if ("roytuts".equals(userName) && "roytuts".equals(userPass)) {
            return Response.status(Response.Status.OK)
                    .entity("Get ToDo for " + id)
                    .type(MediaType.APPLICATION_JSON).build();
        } else {
            return Response.status(Response.Status.OK)
                    .entity("Authentication failed : invalid credentials")
                    .type(MediaType.APPLICATION_JSON).build();
        }
    }

    @POST
    @Path("addToDo")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response addToDo(String toDo) {
        //read headers information to retrieve cookie
        Map<String, Cookie> cookieMap = httpHeaders.getCookies();
        String userName = cookieMap.get("username").getValue();
        String userPass = cookieMap.get("password").getValue();
        //authenticate
        if ("roytuts".equals(userName) && "roytuts".equals(userPass)) {
            return Response.status(Response.Status.OK)
                    .entity("New ToDo " + toDo + " added successfully")
                    .type(MediaType.APPLICATION_JSON).build();
        } else {
            return Response.status(Response.Status.OK)
                    .entity("Authentication failed : invalid credentials")
                    .type(MediaType.APPLICATION_JSON).build();
        }
    }

}

Step 6. Create JUnit test class for testing the service

package com.roytuts.rest.cookie.resources;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation.Builder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.MediaType;

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ToDoResourceTest {

    private HttpServer httpServer;
    private WebTarget webTarget;
    private List<Cookie> cookies;
    private static final URI baseUri = URI
            .create("http://localhost:9090/rest/");

    @Before
    public void setup() throws Exception {
        // create ResourceConfig from Resource class
        ResourceConfig rc = new ResourceConfig(ToDoResource.class);
        // create the Grizzly server instance
        httpServer = GrizzlyHttpServerFactory.createHttpServer(baseUri, rc);
        // start the server
        httpServer.start();
        // configure client with the base URI path
        Client client = ClientBuilder.newClient();
        webTarget = client.target(baseUri);
        if (cookies == null) {
            buildCookies();
        }
    }

    @After
    public void tearDown() throws Exception {
        // if you want to stop the server from the input through keyboard then
        // uncomment below two lines
        // System.out.println(String
        // .format("Application started.%nHit enter to stop it..."));
        // System.in.read();
        // stop the server
        httpServer.shutdown();
    }

    @Test
    public void testGetToDo() {
        webTarget = webTarget.path("todo/getToDo/1");
        Builder builder = webTarget.request();
        //add cookie to the headers
        for (Cookie cookie : cookies) {
            builder.cookie(cookie);
        }
        String response = builder.accept(MediaType.APPLICATION_JSON).get()
                .readEntity(String.class);
        System.out.println("Response: " + response);
    }

    @Test
    public void testAddToDo() {
        webTarget = webTarget.path("todo/addToDo");
        Builder builder = webTarget.request();
        //add cookie to the headers
        for (Cookie cookie : cookies) {
            builder.cookie(cookie);
        }
        String response = builder.accept(MediaType.APPLICATION_JSON).post(
                Entity.entity("NEW TODO", MediaType.APPLICATION_JSON),
                String.class);
        System.out.println("Response: " + response);
    }

    private void buildCookies() {
        cookies = new ArrayList<Cookie>();
        Cookie cookieUser = new Cookie("username", "roytuts");
        Cookie cookiePass = new Cookie("password", "roytuts1");
        cookies.add(cookieUser);
        cookies.add(cookiePass);
    }

}

Step 7. Run the JUnit test class.

Console output when valid credentials are given

Sep 27, 2015 7:55:34 AM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.6 2014-02-18 21:52:53...
Sep 27, 2015 7:55:35 AM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:9090]
Sep 27, 2015 7:55:35 AM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Response: New ToDo NEW TODO added successfully
Sep 27, 2015 7:55:35 AM org.glassfish.grizzly.http.server.NetworkListener shutdownNow
INFO: Stopped listener bound to [localhost:9090]
Sep 27, 2015 7:55:35 AM org.glassfish.grizzly.nio.GracefulShutdownRunner run
WARNING: GRIZZLY0032: Primary shutdown thread interrupted.  Forcing transport termination.
Sep 27, 2015 7:55:35 AM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.6 2014-02-18 21:52:53...
Sep 27, 2015 7:55:35 AM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:9090]
Sep 27, 2015 7:55:35 AM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer-1] Started.
Response: Get ToDo for 1
Sep 27, 2015 7:55:35 AM org.glassfish.grizzly.http.server.NetworkListener shutdownNow
INFO: Stopped listener bound to [localhost:9090]
Sep 27, 2015 7:55:35 AM org.glassfish.grizzly.nio.GracefulShutdownRunner run
WARNING: GRIZZLY0032: Primary shutdown thread interrupted.  Forcing transport termination.

Console output when invalid credentials are given (Just change the username or password in buildCookies() method)

Sep 27, 2015 7:57:04 AM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.6 2014-02-18 21:52:53...
Sep 27, 2015 7:57:04 AM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:9090]
Sep 27, 2015 7:57:04 AM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Response: Authentication failed : invalid credentials
Sep 27, 2015 7:57:04 AM org.glassfish.grizzly.http.server.NetworkListener shutdownNow
INFO: Stopped listener bound to [localhost:9090]
Sep 27, 2015 7:57:04 AM org.glassfish.grizzly.nio.GracefulShutdownRunner run
WARNING: GRIZZLY0032: Primary shutdown thread interrupted.  Forcing transport termination.
Sep 27, 2015 7:57:04 AM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.6 2014-02-18 21:52:53...
Sep 27, 2015 7:57:05 AM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:9090]
Sep 27, 2015 7:57:05 AM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer-1] Started.
Response: Authentication failed : invalid credentials
Sep 27, 2015 7:57:05 AM org.glassfish.grizzly.http.server.NetworkListener shutdownNow
INFO: Stopped listener bound to [localhost:9090]
Sep 27, 2015 7:57:05 AM org.glassfish.grizzly.nio.GracefulShutdownRunner run
WARNING: GRIZZLY0032: Primary shutdown thread interrupted.  Forcing transport termination.

That’s all. Thanks for your reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit | Email Me

Leave a Reply

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