WSO2 ESB supports securing unsecured web services. In this post I'm going to explain how you can secure a web service with WSO2 ESB, using it as an integration layer.
You may have heard of proxy services. A proxy service is a virtual service hosted within an ESB. Simply a proxy service wraps a back-end web service hosted in an application server. A proxy service receives messages that have been sent to a specific endpoint (back-end service) defined in the proxy service configuration. Before forwarding the messages to the relevant endpoint the proxy service can process them if needed, using mediators.
These back-end services may no be secured always. In such a case those unsecured services can be made secured by using the ESB as integration layer. To do that what we need to do is creating a secure proxy service with WS-Security enabled with a specified security policy.
Here are the simple steps to follow to secure a web service.
Open the ESB Management Console.
Create a Proxy Service by clicking on the Services -> Add -> Proxy Service ->Pass Through Proxy in the Main tab. (Here I've selected Pass Through Proxy since I just need to forward messages to the endpoint without performing any processing on them)
Give a name for the Proxy Service and specify the target endpoint. Here I've given the web service URL which is hosted within the Axis2 server.
Then you will be redirected to the List of Services.
You will see the proxy service is shown as 'Unsecured'. Click on 'Unsecured'.
You will be prompted to Enable Security. Select Yes. Then select the UsernameToken as the Basic Scenario.
Click Next. Select user group and Finish.
Now the proxy service is security enabled. You can see the endpoint starting with https:// service dashboard of the proxy service.
Now let's see how to access this web service using a secure client.
REST is an architectural style that used to write a web
service in a certain way. It is based on web-standards and the HTTP protocol. This style was defined by Roy
Fielding in 2000.
In REST architecture the main concept is the Resource which can be uniquely identified by an Uniform Resource Identifier or URI. Every resource supports the HTTP operations.
In this post I'm going to describe how to implement a RESTfull web service which I am going to create as a standalone service with an embedded Jetty server. So you do not need to deploy it in a web container.
This is a simple web service to store and retrieve music track details.
Here is the pom.xml file which contains the relevant dependencies. You can see how the embedded Jetty server is configured through the maven-jetty-plugin and the port being set to 9090.
This web service accepts requests in JSON format and responds with the same format.
Here is the data model Track.java
package com.wso2.training.manorama.model;
/**
* Created with IntelliJ IDEA.
* User: manorama
* Date: 12/4/14
* Time: 10:24 PM
* To change this template use File | Settings | File Templates.
*/
public class Track {
String title;
String singer;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
@Override
public String toString() {
return "Track [title=" + title + ", singer=" + singer + "]";
}
}
Now I will describe you how to implement the RESTfull web service for this. Here is the web service implementation class.
package com.wso2.training.manorama;
import com.wso2.training.manorama.model.Track;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
* Created with IntelliJ IDEA.
* User: manorama
* Date: 12/4/14
* Time: 10:23 PM
* To change this template use File | Settings | File Templates.
*/
@Path("/musicservice")
public class JSONService {
@GET
@Path("/randomtracks")
@Produces(MediaType.APPLICATION_JSON)
public Track getTrackInJSON() {
// Here you can modify this code to get a random track from the available music tracks
Track track = new Track();
track.setTitle("Enter Sandman");
track.setSinger("Metallica");
return track;
}
@POST
@Path("/tracks")
@Consumes(MediaType.APPLICATION_JSON)
public Response createTrackInJSON(Track track) {
String result = "Track saved : " + track;
return Response.status(201).entity(result).build();
}
}
To map the incoming requests, we configure the web.xml (webapp/WEB-INF/web.xml)
When looking at the web service implementation java code, you can see the GET requests with the pattern /randomtracks come to the getTrackInJSON() method. It will respond with a Track object in json format. Note the @Produces(MediaType.APPLICATION_JSON) annotation.
The POST requests comes with the pattern /tracks will create a new Track object and responds with the HTTP 201 OK.The Track object should be in the json format. Note the @Consumes(MediaType.APPLICATION_JSON) annotation
com.sun.jersey.api.json.POJOMappingFeaturetrue
This will map the POJO class to json. Thus the posted json string will be converted into “Track” object automatically.
To deploy this you will need several libraries to be included in the webapp/WEB-INF/lib folder
asm-3.1.jar
jersey-client-1.18.jar
jersey-core-1.18.jar
jersey-json-1.18.jar
jersey-server-1.18.jar
jersey-servlet-1.18.jar
jsr311-api-1.1.1.jar
Since this is a standalone service you do not need to deploy it in a web container. Simply run, $ mvn jetty:run