Search This Blog

Tuesday, 19 December 2017

Securing RESTful Web Services

Securing RESTful Web Services

This post describes how to secure Web services that conform to the Representational State Transfer (REST) architectural style using Java API for RESTful Web Services (JAX-RS).

We can secure the RESTful Web services using one of the following methods
  • Updating the web.xml deployment descriptor to define security configuration.
  • Using the javax.ws.rs.core.SecurityContext  interface to implement security programmatically.
  • Applying annotations to your JAX-RS classes. 

Securing RESTful Web Services Using web.xml

We secure RESTful Web services using the web.xml deployment descriptor as we would for other Java EE Web applications.
To secure your RESTful Web service using basic authentication, perform the following steps:
  1. Define a <security-constraint> for each set of RESTful resources (URIs) that you plan to protect.
  2. Use the <login-config> element to define the type of authentication you want to use and the security realm to which the security constraints will be applied. 
  3. Define one or more security roles using the <security-role> tag and map them to the security constraints defined in step 1. 
  4. To enable encryption, add the <user-data-constraint> element and set the <transport-guarantee> subelement to CONFIDENTIAL 

<web-app>
    <servlet>
        <servlet-name>RestfulServlet</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RestfulServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <security-constraint>
         <web-resource-collection>
             <web-resource-name>Employees</web-resource-name>
             <url-pattern>/employees</url-pattern>
             <http-method>GET</http-method>
             <http-method>POST</http-method>
         </web-resource-collection>
         <auth-constraint>
             <role-name>admin</role-name>
         </auth-constraint>
    </security-constraint>
        <login-config>
            <auth-method>BASIC</auth-method>
            <realm-name>default</realm-name>
        </login-config>
    <security-role>
        <role-name>admin</role-name>
    </security-role>
</web-app>

Securing RESTful Web Services Using SecurityContext

The javax.ws.rs.core.SecurityContext  interface provides access to security-related information for a request. The SecurityContext provides functionality similar to javax.servlet.http.HttpServletRequest, enabling you to access the following security-related  information:
  1. java.security.Principal object containing the name of the user making the request.
  2. Authentication type used to secure the resource, such as BASIC_AUTH, FORM_AUTH, and CLIENT_CERT_AUTH.
  3. Whether the authenticated user is included in a particular role.
  4. Whether the request was made using a secure channel, such as HTTPS.

You access the SecurityContext  by injecting an instance into a class field, setter method, or method parameter using the javax.ws.rs.core.Context annotation.
package com.rest.helloworld;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.Context;

...

@Path("/stateless")
@Stateless(name = "JaxRSStatelessEJB")
public class MyApp {
...
        @GET
        @Produces("text/plain;charset=UTF-8")
        @Path("/hello")
        public String sayHello(@Context SecurityContext sc) {
                if (sc.isUserInRole("admin"))  return "Hello World!";
                throw new SecurityException("User is unauthorized.");
        }

Securing RESTful Web Services Using Annotations

The javax.annotation.security  package provides annotations, defined below, that you can use to secure your RESTful Web services.
Restful Annotations
Restful Annotations
package com.rest.helloworld;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.annotation.Security.RolesAllowed;


@Path("/helloworld")
@RolesAllowed({"ADMIN", "ORG1"})
public class helloWorld {

   @GET
   @Path("sayHello") 
   @Produces("text/plain")
   @RolesAllows("ADMIN")
   public String sayHello() {
      return "Hello World!";
   }
}