Mar 24, 2016

Secure RESTful web service using BASIC authentication with Spring and CXF

1. Eclipse Web Project Structure
 


























2. Create The Java Code

2.1. Customer entity class.

package com.test.restful;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Customer {
   
    private String name;
    private String address;
    private int age;
   
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}


2.2. CustomerService interface

package com.test.restful;

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

import org.apache.cxf.jaxrs.model.wadl.Description;
import org.apache.cxf.jaxrs.model.wadl.DocTarget;

@Path("/customer")
public interface ICustomerService {

    @GET
    @Description(value = "Resource", target = DocTarget.RESOURCE)
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN,
            MediaType.APPLICATION_XML })
    @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN,
            MediaType.APPLICATION_XML })

    @Path("/getdetails")
    public Customer getCustomerDetails();

    @POST
    @Description(value = "Resource", target = DocTarget.RESOURCE)
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN,
            MediaType.APPLICATION_XML })
    @Path("/addcustomer")
    public GenericResponse addCustomer(@Description("Input customer") Customer customer);
}

2.3. CustomerServiceImpl class 


package com.test.restful;
import org.springframework.stereotype.Component;

@Component("customerService")
public class CustomerServiceImpl implements ICustomerService {
    @Override
    public Customer getCustomerDetails() {
        // TODO Auto-generated method stub
        Customer customer = new Customer();
        customer.setName("Muni");
        customer.setAddress("Bangalore");
        customer.setAge(37);
        return customer;
    }
    @Override
    public GenericResponse addCustomer(Customer customer) {
        // TODO Auto-generated method stub
        GenericResponse response = new GenericResponse();
        if(customer!=null && customer.getAge()>=18){
            response.setMessage("Customer added");
            response.setSuccess(true);
        }else{
            response.setMessage("Customer too young to added");
            response.setSuccess(false);
        }
        return response;
    }
}






2.4. GenericResponse class


package com.test.restful;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class GenericResponse implements Serializable{

    private static final long serialVersionUID = 1L;
    private boolean success;
    private String message;

    public boolean isSuccess() {
        return success;
    }
    public void setSuccess(boolean success) {
        this.success = success;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

3.  /WEB-INF/application-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <context:annotation-config />
    <context:component-scan base-package="com.test.restful" />
   
    <jaxrs:server id="restfulId" address="/rest">
        <jaxrs:serviceBeans>
            <ref bean="customerService" />
        </jaxrs:serviceBeans>
        <!-- jax jackson -->
        <jaxrs:providers>
            <bean id="jacksonProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"></bean>
        </jaxrs:providers>
    </jaxrs:server>

</beans>










4 . security-constraint configuration in application web.xml file (WEB-INF/web.xml)



<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>RestfulServer</display-name>
    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/application-context.xml</param-value>
    </context-param>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>rest</web-resource-name>
            <url-pattern>/rest/customer/getdetails</url-pattern>
            <http-method>GET</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>member</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>BASIC</auth-method>
    </login-config>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
</web-app>

5. Add user and role in Tomcat server (apache-tomcat-8.0.30/conf/tomcat-users.xml)

  • username – Username this user must log on with.
  • password – Password this user must log on with (in clear text).
  • roles        – Comma-delimited list of the role names associated with this user.
  <role rolename="tomcat"/>
  <role rolename="member"/>
  <role rolename="admin"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="knmuni" password="knmuni123" roles="member,admin"/>

6. pom.xml

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>RestfulServer</groupId>
  <artifactId>RestfulServer</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>RestfulServer</name>
<build>
        <finalName>RestfulServer</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-bundle-jaxrs</artifactId>
            <version>2.7.14</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-jaxrs</artifactId>
            <version>1.9.13</version>
        </dependency>

    </dependencies>
</project>


7. Test "getdetails" call .
















Thank you ! :)


No comments: