Friday, February 14, 2014

JAX-WS Web Service with SOAP 1.2

JAX-WS uses the SOAP 1.1 for the Web Services if the SOAP version is not explicitly defined (By Default). this is the default behavior.  if you want to use SOAP 1.2 for your web service, then you may need to explicitly declare it in the web service. then following annotation can be used to explicitly define the SOAP version of the web service.

For SOAP 1.2

@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING) 


Sample Java Implementation

package com.chathurangaonline.sample.jaxws;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;

/**
 * <p>
 *     Service Implementation Bean (SIB) for CalculatorService endpoint interface
 * </p>
 */
@WebService
@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING)
public class CalculatorServiceImpl implements CalculatorService{


    @WebMethod
    public long add(long number1, long number2) {
        return number1+number2;
    }

    @WebMethod
    public long subtract(long number1, long number2) {
        return number1+number2;
    }

    @WebMethod
    public long multiply(long number1, long number2) {
        return number1*number2;
    }
}
 
Hope this will be helpful for you!

Thanks and Regards

Chathuranga Tennakoon
www.chathurangaonline.com

Wednesday, February 12, 2014

How to Determine the SOAP Version of a Message

References :- http://wso2.com/library/articles/differentiating-between-soap-versions-looking-soap-message/


Thanks Mr. Eran Chinthaka for the Nice Article!

Thursday, February 6, 2014

Why WS-Security over HTTPS?

this is a very good and clear article that i have ever seen in my life related to the use of the WS-Security over HTTPS. i am just re-sharing the article for your reference. in order to give the credit for the original author, i am sharing the original sources as the reference here.

Source: - http://www.cloudidentity.com/blog/2005/04/25/END-TO-END-SECURITY-OR-WHY-YOU-SHOULDN-T-DRIVE-YOUR-MOTORCYCLE-NAKED/





So it goes like this. Suppose you are naked, and you have to drive your motorcycle to a certain destination.

In the (A) case you go through a transparent tunnel: your only hope of not being arrested for obscene behaviour is that nobody is looking. That is not exactly the most secure strategy you can come out with… (notice the sweat drop from the guy forehead :-)). That is equivalent to a POST in clear, and when I say “equivalent” I mean it.


In the (B) case, you are in a better situation. The tunnel is opaque, so as long as you travel into it your public record is safe. However, this is still not the best situation. You still have to leave home and reach the tunnel entrance, and once outside the tunnel probably you’ll have to get off and walk somewhere… and that goes for HTTPS. True, your message is safe while it crosses the biggest chasm: but once you delivered it on the other side you don’t really know how many stages it will have to go through before reaching the real point where the data will be processed. And of course all those stages could use something different than HTTP: a classical MSMQ which buffers requests which can’t be served right away, for example. What happens if somebody lurks your data while they are in that preprocessing limbo?


The complete solution (c) in this metaphor is painfully trivial: get some darn clothes on yourself, and especially the helmet while on the motorcycle!!! So you can safely go around without having to rely on opaqueness of the environments. The metaphor is hopefully clear: the clothes come with you regardless of the mean or the surrounding infrastructure, as the message level security does. Furthermore, you can decide to cover one part but reveal another (and you can do that on personal basis: airport security can get your jacket and shoes off, while your doctor may have a higher access level), but remember that short sleeves shirts are bad practice even if you are proud of your biceps :-) (better a polo, or a t-shirt).

I’m happy to say that she got the point! I have to say that the clothes metaphor is very powerful: I was tempted to use it for introducing the concept of policy (disco clubs won’t let you in sport shoes; you can’t go to withdraw money in a bank in your underwear, while this is perfectly acceptable look while balancing yourself on a surf; and so on) but I thought that for one afternoon it was enough


Thanks
Chathuranga

Source:- http://www.cloudidentity.com/blog/2005/04/25/END-TO-END-SECURITY-OR-WHY-YOU-SHOULDN-T-DRIVE-YOUR-MOTORCYCLE-NAKED/

Thursday, January 16, 2014

JAX-WS (SOAP Web Services) with JAXB

JAXB - Java Architecture for XML Binding. support for marshalling and unmarshalling.

marshalling :- converting java objects to XML files/contents

unmarshalling :- converting XML contents back to the java objects


here i have develop a sample application to demonstrate simple java web service with JAXB support.

you can get the fully source code of the project with following gitHub Repo.

https://github.com/chathurangat/jax-ws-jaxb-sample-app


this is just a sample implementation with some hard coded values in the back-end.


WebService

Employee.java

package com.chathurangaonline.samples.jax.ws.jaxb.model;

public class Employee {

    private int id;
    private String empId;
    private String name;
    private String email;
    private String website;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getEmpId() {
        return empId;
    }

    public void setEmpId(String empId) {
        this.empId = empId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getWebsite() {
        return website;
    }

    public void setWebsite(String website) {
        this.website = website;
    }
}




EmployeeService.java

package com.chathurangaonline.samples.jax.ws.jaxb;

import com.chathurangaonline.samples.jax.ws.jaxb.model.Employee;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface EmployeeService {

    @WebMethod
    Employee create(Employee employee);

    @WebMethod
    Employee findEmployeeById(String empId);
}




EmployeeServiceImpl.java

package com.chathurangaonline.samples.jax.ws.jaxb;

import com.chathurangaonline.samples.jax.ws.jaxb.model.Employee;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;


@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class EmployeeServiceImpl implements EmployeeService{

    @WebMethod
    public Employee create(Employee employee) {
        //todo sample implementation
        if(employee!=null && employee.getEmail()!=null && employee.getEmail().equals("chathuranga.t@gmail.com")){
            employee.setEmpId("emp4235");
            employee.setName("chathuranga tennakoon");
            employee.setWebsite("www.chathurangaonline.com");
        }
        return employee;
    }

    @WebMethod
    public Employee findEmployeeById(String empId) {
        //todo sample implementation
        if(empId!=null && empId.equals("emp4235")){
            Employee employee = new Employee();
            employee.setId(123);
            employee.setEmpId("emp4235");
            employee.setName("chathuranga tennakoon");
            employee.setWebsite("www.chathurangaonline.com");
            employee.setEmail("chathuranga.t@gmail.com");
        }
        Employee employee = new Employee();
        employee.setName("chathuranga tennakoon");
        return employee;
    }
}




web.xml

<!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>Archetype Created Web Application</display-name>

    <listener>
        <listener-class>
            com.sun.xml.ws.transport.http.servlet.WSServletContextListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>empService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>empService</servlet-name>
        <url-pattern>/empServiceUrl</url-pattern>
    </servlet-mapping>
</web-app>





sun-jaxws.xml

<?xml version="1.0" encoding="UTF-8"?>
<endpoints
        xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
        version="2.0">
    
    <endpoint name="empService" 
              implementation="com.chathurangaonline.samples.jax.ws.jaxb.EmployeeServiceImpl" 
              url-pattern="/empServiceUrl"/>
</endpoints>




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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.chathurangaonline.jax.ws.samples</groupId>
    <artifactId>jaxb-sample-web-service</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>
    <name>jaxb-sample-web-service Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
    <build>
        <finalName>employee-service</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <!--compiles with java 7-->
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <!--WAR plugin-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.5</version>
            </plugin>
        </plugins>
    </build>
</project>








WebClient

web client can be generated with the wsimport tool. the sample command is as follows. replace the value with your configurations.

wsimport  -keep  -verbose -d /home/chathuranga/Projects/jax-ws-tutorial/jax-ws-jaxb-sample-app/webClient/jaxb-client/src/main/java/  http://localhost:8080/employee-service/empServiceUrl?wsdl


EmpServiceClient.java


import com.chathurangaonline.samples.jax.ws.jaxb.Employee;
import com.chathurangaonline.samples.jax.ws.jaxb.EmployeeServiceImpl;
import com.chathurangaonline.samples.jax.ws.jaxb.EmployeeServiceImplService;

/**
 * <p>
 *     sample web service client implementation
 * </p>
 * 
 * @Author Chathuranga Tennakoon
 */
public class EmpServiceClient {

    public static void main(String[] args) {

        EmployeeServiceImplService employeeServiceImplService = new EmployeeServiceImplService();
        EmployeeServiceImpl employeeService = employeeServiceImplService.getEmployeeServiceImplPort();

        //creating the employee
        Employee employeeOb = new Employee();
        employeeOb.setEmail("chathuranga.t@gmail.com");

        Employee employeeCreated = employeeService.create(employeeOb);

        System.out.println(" employee created  ["+employeeCreated.getEmpId()+"]");

        //find the employee with id
        Employee employee = employeeService.findEmployeeById("emp4235");

        System.out.println(" employee found ["+ employee.getName()+"]");
    }
}






hope this will be helpful for you!


Thanks
Cahthuranga Tennakoon
www.chathurangaonline.com


Saturday, November 30, 2013

Some Interesting gradle commands.

once the gradle is installed, now it is time to explore the functionalities of the gradle.


1. generating new java project with gradle.

   it is possible to generate simple java project with maven as follows.
 
   maven
   mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart

  the gradle also supported to generate project as follows.

  gradle
  gradle init --type java-library


2. converting the maven project to gradle.

it is possible to convert the maven project to gradle without any problem. it will create the build.gradle file and declare all the dependencies and other plugins declared in the pom.xml into the build.gradle file. In order to convert the maven project to gradle, you need to execute the following command  from the same directory of the project where the pom.xml file is located.

 gradle init



Hope this will helpful for you!

Thanks
Chathuranga Tennakoon
chathuranga.t@gmail.com
http://www.chathurangaonline.com







Thursday, November 28, 2013

How to install Gradle on Linux (Ubuntu)

if you dont know gradle, please go though the following website to get an understanding about gradle.

Gradle project home page :- http://www.gradle.org


follow the steps give below to install the gradle on your develop environment. (Linux based)

1. download the gradle distribution from the gradle website.

    http://www.gradle.org/downloads


2. extract the downloaded gradle distribution in any directory in your PC.

 
3. then add the GRADLE_HOME environmental variable. to add the environmental variable, follow the below instructions.

    3.1 sudo  gedit .bashrc
 
    3.2  add the following to the bottom of the .bashrc file

    GRADLE_HOME=<path to gradle bin file>  (e.g. /opt/gradle/gradle-1.5/bin )
    export GRADLE_HOME
    PATH=$PATH:$GRADLE_HOME
    export PATH
  
    3.2  source .bashrc



4. once the above changes are done, run gradle in the terminal to check whether gradle is properly installed.




Thanks
Chathuranga Tennakoon
chathuranga.t@gmail.com
http://www.chathurangaonline.com


 

Sunday, November 10, 2013

How to configure Tomcat to support SSL or https

first you need to create a keystore with following command.

 keytool -genkey -keyalg RSA -keystore /home/chathuranga/test_chathu.keystore

then answers for the questions that prompts sequentially. once the keystore is created, you can use the following command to check whether your keystore is there.

keytool -list -keystore /home/chathuranga/test_chathu.keystore


Now it is the time to do the tocat SSL configuration.

In tomcatHome/conf/server.xml file, change the SSL configuration as follows.

 <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
           keystoreFile="/home/chathuranga/test_chathu.keystore"
           keystorePass="password" />


Then restart the tomcat server and try to access the following URL.

https://locahost:8443


you will notice that, your tomcat installation supports SSL(HTTPS) now.


Thanks
Chathuranga Tennakoon
chathuranga.t@gmail.com

Saturday, November 2, 2013

Application Authentication for JAX-WS web services

 the fully source code for this example can be found at  following gitHub repository.

Download code From GitHub

clone the project from gitHub and use the maven to build the project.
then deploy the web service in the tomcat server. (just copy the war file and i have already done the required web.xml and sun-haxws.xml configurations.)

if you want  to know, how to deploy the web service in tomcat, you can refer my previous blog post here

once the web service is deployed, you can run the web service client to test the web service and see how it works.


In application authentication, then authentication logic will be implemented there in the web service. therefore the web service will be responsible for handling the user authentication.

the web service client will send the user credentials (username and password) to the web service. please refer the following WebService Client.


package com.chathurangaonline.jaxws.samples.client;

import com.chathurangaonline.jaxws.samples.impl.*;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.MessageContext;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class WebServiceClientImpl {

    public static void main(String [] args){

        CalculatorServiceImplService calculatorServiceImplService = new CalculatorServiceImplService();
        CalculatorServiceImpl calculatorService = calculatorServiceImplService.getCalculatorServiceImplPort();

        Map<String, Object> req_ctx = ((BindingProvider)calculatorService).getRequestContext();
        Map<String, List<String>> headers = new HashMap<String, List<String>>();

        //setting up the username and password 
        headers.put("Username", Collections.singletonList("chathuranga"));
        headers.put("Password", Collections.singletonList("chathu@123"));
        req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);

        //in order to invoke the add method, you need to have valid login credentials
        double answer =  calculatorService.add(45,10);
        System.out.println(" answer is ["+answer+"]");
    }
}


The web service will extract the user login credentials (username and password) from the HTTP Request Headers and  will perform the user authentication.
(here we have hard coded the username and password for the demostration purpose and to make it more simple. in the production mode, you need to move then  database) 
 if the user authentication is successful, he will be able to access the web service. otherwise it will throw a HttpException as implemented.  refer the following web service implementation.


package com.chathurangaonline.jaxws.samples.impl;

import com.chathurangaonline.jaxws.samples.CalculatorService;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPException;
import java.util.List;
import java.util.Map;


@WebService
public class CalculatorServiceImpl implements CalculatorService{

    @Resource
    private WebServiceContext webServiceContext;

    @Override
    public double add(double num1, double num2) {
        //todo username and password was hardcoded only for the demonstration purpose. this should be configured to look up from database or somewhere else
        if(isAuthenticated("chathuranga","chathu@123")){
            //allowing the operation for the authenticated user
            return num1 + num2;
        }
        else{
            //non-authenticated user.
            throw  new HTTPException(401);
        }
    }

    @Override
    public double multiply(double num1, double num2) {
        return num1 * num2;
    }


    /**
     * <p>
     *     method for checking the application level authentication using the username and password provided.
     * </p>
     * @param username - username provided as {@link java.lang.String}
     * @param password - password provided as {@link java.lang.String}
     * @return {@link java.lang.Boolean} (true if user authenticated, otherwise false)
     */
    private boolean isAuthenticated(String username, String password){
        if(username!=null && password!=null){
            MessageContext messageContext = webServiceContext.getMessageContext();
            Map httpHeaders  = (Map) messageContext.get(MessageContext.HTTP_REQUEST_HEADERS);

            List usernameList  = (List) httpHeaders.get("username");
            List passwordList = (List) httpHeaders.get("password");

            if((usernameList!=null && usernameList.contains(username)) && (passwordList!=null && passwordList.contains(password))){
                return true;
            }
        }
        return false;
    }
}


The main problem with Application Authentication is the mix of security logic with the business logic might mess the code. it add some unnecessary complexity for the code with tight coupling. as a solution for this, we can go for the Container Managed Authentication and that will be my next blog post ;)

Thanks
Chathuranga Tennakoon
chathuranga.t@gmail.com