Sunday, October 14, 2012

Optimized Light Weight XPATH Parser using AXIOM and Antlr Parser Generator

If we talk about parsing a XPath expression we can use the XPath engines like Jaxen or AXIOM XPath which is built on top of AXIOM. These XPath engines supports the full specification of XPath.
But most of the time our use-case is not having the full XPath specification parsing support but a quick and optimized way of parsing XPath. Because most of the time we are parsing XPath expressions like "/data/book/name", which will point to a single element of a XML.
So If we have some-kind of fact that we want the first match of XPath or we have only one match for XPath expression, we don't need to open the full tree of XML.
For a example to parse an XPath expression like "/data/book/author/name" against following XML, we don't have to look at lecturers element at all.

  
       
   Andun
   Sri Lanka
       
  
  
       
           Mr_Thilak_Fernando
           
               108
               328
               568
           
      
      
           Ms_Pivithuru
           
               88
               328
               568
               808
               1048
           
      
      
           Mr_Nisansa
           
               88
               328
               568
               808
               1048
           
      
  
So in this post I will describe a implementation of a High Performance Custom Xpath Parser which will have following conditions,
  • Will return the first match of XPAth expression 
If we have an XPath like, "/data/book/author/name". This parser only return the <name>Andun</name> element only.

    
        
        Andun
        Sri Lanka
    
    
    
        
        Sameera
        Sri Lanka
        
    
  • Only return a single element as result. No Sets are returned. 
If we have an XPath like, "/data/book/author/name". This parser only return the <name>Andun</name> element only. While the XPath Spec defines the result of this expression is <name>Andun</name><name>Sameera</name>.

    
        
        Andun
        Sri Lanka
    
    
    
        
            
            Sameera
            Sri Lanka
            
        
    
  • Only parse absolute XPath expressions. 
This kind of XPath expression are accepted "/data/book/author/@age" while "//author/name" kind of expressions are rejected.
  • Complex XPath expression which have predicates, logical combinations of results etc. will be not be eligible.
To implement this we have used this kind of architecture on top of the AXIOM data model for a XML. Created small components which are responsible to do simple operations to AXIOM data model. For Example,
  • Component to return XML node if it matches some conditions.
  • Component to return set of children of a XML node if it matches some conditions.
  • Component to return an attribute of a XML node.
Each of these components get a OMElement as the input and it will output the result. Also we can specify some conditions to get the result. So joining these components as a chain we can get the result of a XPath expression.


Here the XML is passed to the first component. Then the result of the first component is passed to the second. Like wise the chain is created. So the result of the final component is the result of the XPath expression.
So likewise we can create a simple XPath parser. Here the advantages are, 
  • It will not have to do check the all spec of the XPath spec which is useless for most of the use-case. 
  • It don't have to traverse the all big tree of XML to get the result.
  • AXIOM will not load the XML elements to the memory which are not traversed.
So this new Custom XPath parser will do following,
  • When we give a XPath expression to the parser it will create the component chain which will do the processing to get the result of the XPath.
  • When the parsing happens, the input XML is passed though the component chain and output the result.
To create the component chain we have analyze the given XPATH expression. For that We use Antlr Parser Generator.
  • We have to check weather the given XPath expression can be evaluated using Parser.
  • If the expression can be parsed, we have to create the above dicribed component chain. 
We have used a Antlr Grammar for XPath 1.0. Using that grammar we have generated a Lexer, Parser and Walker for  XPath 1.0. When a XPath expression is given Antlr will analyze the expression using the given Grammar which we have created. Then It will generate a Abstract Syntax tree like the following,


The using this generated tree we are building the  component chain. Each node of this tree is responsible to add some JAVA code to the XPath parser. When the tree is traversed a Java class will be generated. Using that we can parse a XPath expression.
Also when this tree found a XPath expression which cant be evaluated using our Custom Parser it will throw an Exception. So we can develop a logic to catch that exception and call a XPath parser like Jaxen to do processing.
Also to further optimize the processing we can use a input stream of a XML. So AXIOM will only read the necessary part of that stream to process the XPath expression.
Following JAVA class shows the implementation of the XPath parser. Please contact me to further clarifications.

package org.wso2.carbon.custom_xpath;

import org.antlr.runtime.RecognitionException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.llom.util.AXIOMUtil;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.wso2.carbon.custom_xpath.compiler.CustomXPATHCompiler;
import org.wso2.carbon.custom_xpath.compiler.exception.CustomXPATHCompilerException;
import org.wso2.carbon.custom_xpath.exception.CustomXPATHException;
import org.wso2.carbon.custom_xpath.parser.custom.CustomParser;
import org.wso2.carbon.custom_xpath.parser.custom.components.ParserComponent;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class CustomXPATH {

    private String xPath;
    private CustomParser customParser;
    private HashMap<String,String> prefixNameSpaceMap;

    /**
     * This constructor is responsible For Create a Custom XPATH Parser Object
     * @param xPath is the XPATH String
     * @param prefixNameSpaceMap  Prefix:NameSpace Map
     * @throws CustomXPATHException
     */
    public CustomXPATH(String xPath,HashMap<String,String> prefixNameSpaceMap) throws CustomXPATHException {
        setPrefixNameSpaceMap(prefixNameSpaceMap);
        setxPath(xPath);
        try {
            setCustomParser(CustomXPATHCompiler.parse(getxPath()));
        } catch (RecognitionException e) {
            throw new CustomXPATHException(e);
        }
        catch(CustomXPATHCompilerException exception){
            //Here is the catch clause for XPath expressions which the Custom Parser cant process. So we can call A parser like Jaxen here.
        }
    }

    /**
     * This will return the XPATH expression's result when you provide a Input Stream To a XML
     * @param inputStream for a XML
     * @return  Result of the XPATH expression
     * @throws XMLStreamException
     * @throws CustomXPATHException
     */
    public  String getStringValue(InputStream inputStream) throws XMLStreamException, CustomXPATHException {
        if(customParser!=null){
            return getCustomParser().process(inputStream);
        }
        else{
            //Here the Jaxen will do the processing
        }
    }

    /**
     * This will return the XPATH expression's result when you provide a Input Stream To a XML
     * @param envelope for a XML
     * @return  Result of the XPATH expression
     * @throws XMLStreamException
     * @throws CustomXPATHException
     */
    public  String getStringValue(String envelope) throws XMLStreamException, CustomXPATHException {
        return getStringValue(new ByteArrayInputStream(envelope.getBytes()));
    }

    public String getxPath() {
        return xPath;
    }

    public void setxPath(String xPath) {
        this.xPath = xPath;
    }

    public CustomParser getCustomParser() {
        return customParser;
    }

    public void setCustomParser(CustomParser customParser) {
        this.customParser = customParser;
    }

    public HashMap<String, String> getPrefixNameSpaceMap() {
        return prefixNameSpaceMap;
    }

    public void setPrefixNameSpaceMap(HashMap<String, String> prefixNameSpaceMap) {
        this.prefixNameSpaceMap = prefixNameSpaceMap;
        ParserComponent.setPrefixNameSpaceMap(prefixNameSpaceMap);
    }

}

Tuesday, October 9, 2012

Securing an exisiting WebApp using Entitlement Servlet Filter

Entitlement Servlet Filter is for check the Authorization of the requests which are coming to a webapp. This guide will tel you how to add that to a existing web of yours. You can read more about Entitlement Servlet Filter Here.

The steps to add Entitlement Servlet Filter to your Web App :

  • Add one of J2EE Authentication Mechanism to the WebApp. (Still Entitlement Filter Support Basic Auth Only). To do this task add following to the web.xml of your WebApp.
     <security-constraint>
        <display-name>Example Security Constraint</display-name>
        <web-resource-collection>
            <web-resource-name>Protected Area</web-resource-name>
        <!-- Protected URL -->
            <url-pattern>/protected.jsp</url-pattern>
            <!-- If you list http methods, only those methods are protected -->
            <http-method>DELETE</http-method>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
            <http-method>PUT</http-method>
        </web-resource-collection>
        <auth-constraint>
            <!-- Anyone with one of the listed roles may access this area -->
            <role-name>admin</role-name>
        </auth-constraint>
    </security-constraint>

    <!-- Default login configuration uses form-based authentication -->
    <login-config>
        <auth-method>BASIC</auth-method>
        <!--<auth-method>FORM</auth-method>-->
        <realm-name>Example Form-Based Authentication Area</realm-name>
        <form-login-config>
            <form-login-page>/protected.jsp</form-login-page>
        </form-login-config>
    </login-config>

    <!-- Security roles referenced by this web application -->
    <security-role>
        <role-name>everyone</role-name>
    </security-role>
    <security-role>
        <role-name>admin</role-name>
    </security-role>

  • Engage the Entitlement Servlet Filter. To do this task add following to the web.xml of your WebApp.
    <!-- Filter mappings used to configure URLs that need to be authorized  -->
    <filter-mapping>
        <filter-name>EntitlementFilter</filter-name>
        <url-pattern>/protected.jsp</url-pattern>
    </filter-mapping> 

  • Provide necessary parameters to the Entitlement Servlet filter. To do this task add following to the web.xml of your WebApp.
    <!-- The scope in which the subject would be available.  Legal values are basicAuth, request-param, request-attribute, session -->
    <context-param>
        <param-name>subjectScope</param-name>
        <param-value>basicAuth</param-value>
    </context-param>

    <!-- The name of the identifier by which to identify the subject -->
    <context-param>
        <param-name>subjectAttributeName</param-name>
        <param-value>username</param-value>
    </context-param>

    <!-- The username to perform EntitlementService query-->
    <context-param>
        <param-name>userName</param-name>
        <param-value>admin</param-value>
    </context-param>

    <!-- The password to perform EntitlementService query -->
    <context-param>
        <param-name>password</param-name>
        <param-value>admin</param-value>
    </context-param>

    <!-- The URL to perform EntitlementService query-->
    <context-param>
        <param-name>remoteServiceUrl</param-name>
        <param-value>https://localhost:9443/services/</param-value>
    </context-param>
    
    <!-- EntitlementFilter Settings -->
    <filter>
        <filter-name>EntitlementFilter</filter-name>
        <filter-class>org.wso2.carbon.identity.entitlement.filter.EntitlementFilter</filter-class>

        <!--Client Class that extends AbstractEntitlementServiceClient. Legal values are basicAuth, soap and thrift.
        Default is 'thrift'.-->
        <init-param>
            <param-name>client</param-name>
            <param-value>basicAuth</param-value>
        </init-param>

        <!--Decision caching at PEPProxy. Legal values are simple and carbon.-->
        <init-param>
            <param-name>cacheType</param-name>
            <param-value>simple</param-value>
        </init-param>

        <!--Maximum number of cached entries. Legal values are between 0 and 10000 -->
        <init-param>
            <param-name>maxCacheEntries</param-name>
            <param-value>1000</param-value>
        </init-param>

        <!-- Time interval for which cached entry is valid.-->
        <init-param>
            <param-name>invalidationInterval</param-name>
            <param-value>100000</param-value>
        </init-param>

        <!-- URL ro redirect to if authorization fails -->
        <init-param>
            <param-name>authRedirectUrl</param-name>
            <param-value>/index.jsp</param-value>
        </init-param>

    <!-- This will be used if the transport type is thrift. -->
        <init-param>
            <param-name>thriftHost</param-name>
            <param-value>localhost</param-value>
        </init-param>

        <!-- This will be used if the transport type is thrift.-->
        <init-param>
            <param-name>thriftPort</param-name>
            <param-value>10500</param-value>
        </init-param>

    </filter> 


So after following these steps your webApp is successfully secured with Entitlement Filter. You can find a sample project here.
Also make sure that you have to put the org.wso2.carbon.identity.entitlement.filter_4.0.2.jar, org.wso2.carbon.identity.entitlement.proxy_4.0.2  and org.wso2.carbon.identity.entitlement.stub_4.0.0.jar to your java classpath. The links for those jar is here. Also you can build those jars by using these links.

https://svn.wso2.org/repos/wso2/carbon/platform/trunk/service-stubs/org.wso2.carbon.identity.entitlement.stub/
https://svn.wso2.org/repos/wso2/carbon/platform/trunk/components/identity/org.wso2.carbon.identity.entitlement.proxy/
https://svn.wso2.org/repos/wso2/carbon/platform/trunk/components/identity/org.wso2.carbon.identity.entitlement.filter/

Saturday, October 6, 2012

Binary Relay - WSO2 ESB : One Major Feature Behind the Success

WSO2 Enterprise Service Bus have bulk of features and components which will help to have a good Enterprises Level Service Integration. The Architecture and the Components of WSO2 ESB explains that more. The Users of WSO2 ESB can have lot of flexibility in Routing Messages, Security , QoS,Monitoring etc.
When we focus about the Performance of the WSO2 ESB, I have identified a special feature which is behind. That is the Binary Relay of WSO2 ESB. In the common scenario the routing and manipulation of the messages inside WSO2 ESB happens on the details given in the Payload. But that will add a overhead to processing. So that will limit the performance, while having the flexibility of processing messages.
If we can live without this high level of flexibility of message processing we can increase the performance. That is the main fact behind the Binary Relay feature of ESB. In this mod of ESB, message payload is not touched. The routing of messages happen considering transport level headers. The incoming message will be added to a Dummy SOAP message as a Data Stream. Then the dummy message will pass through the processing pipeline of the ESB. Following diagram shows that functionality,



Also we can recreate some functionality which given in the normal mod of the ESB. Those recreated functionality will be good in performance.
These days I am working on such R&D works at WSO2. So I feels really interesting about this feature. You can read more about Binary Relay in these links,

Thursday, September 6, 2012

XACML Policy Enforcement Point(PEP) Proxy for WSO2 Identity Server

As you all know The WSO2 Identity Server provides  entitlement management  by XACML fine-grained policy based access control. In  this post I will introduce a Proxy Components for use this functionality in JAVA applications. This will make the users life easy in following ways,
  • User have to invoke a method in the proxy to get a entitlement decision.
  • User don't have to implement XACML request related things to use a XACML policy hosted in IS. The proxy hides those complexity from user.
  • Entitlement requests can be sent either using XACML 3.0 or  XACML 2.0.
  • The proxy provides list of methods which will most of the authorization request scenarios which a user can have.
  • User can use SOAP, Thrift or JSON to PDP PEP communication. User doesn't have to worry about the communication implementation.
  • Several PEPs can use same Proxy to communicate with several PDPs(WSO2 IS instances) at the same time.
Following diagram will show the functionality of the PEP Proxy,


Here XACML PEP can be any JAVA application. I have given a example application in my previous blog posts, http://www.insightforfuture.blogspot.com/2012/07/providing-xacml-fine-grained.html and http://www.insightforfuture.blogspot.com/2012/07/providing-xacml-fine-grained_22.html. In that I have described a Servlet Filter which uses this PEP proxy for give authorization to webapps.

The following list will show the API methods given in PEP Proxy,
  • String getDecision(Attribute[] attributes)
  • String getDecision(Attribute[] attributes, String appId) 
  • String getDecision(String subject, String resource, String action, String environment)
  • String getDecision(String subject, String resource, String action, String environment, String appId)
  • boolean subjectCanActOnResource(String subjectType, String alias, String actionId,
                                               String resourceId, String domainId) 
  • boolean subjectCanActOnResource(String subjectType, String alias, String actionId,
                                               String resourceId, String domainId, String appId)
  • boolean subjectCanActOnResource(String subjectType, String alias, String actionId,
                                               String resourceId, Attribute[] attributes, String domainId)
  • boolean subjectCanActOnResource(String subjectType, String alias, String actionId,
                                               String resourceId, Attribute[] attributes, String domainId, String appId)
  • List<String> getActionableChidResourcesForAlias(String alias, String parentResource,
                                                               String action)
  • List<String> getActionableChidResourcesForAlias(String alias, String parentResource,
                                                               String action, String appId) 
  • List<String> getResourcesForAlias(String alias)
  • List<String> getResourcesForAlias(String alias, String appId)
  • List<String> getActionableResourcesForAlias(String alias)
  • List<String> getActionableResourcesForAlias(String alias, String appId)
  • List<String> getActionsForResource(String alias, String resources)
  • List<String> getActionsForResource(String alias, String resources, String appId)
Here you can see that there are duplicates of same method with "String appId" and without. When the proxy is initialized it will assign a default primary PEP as defaultAppId. That means the PDP mapping for the defaultAppId is used for make the queries. When  we specify a specific PEP configuration by giving "String appId", PEP Proxy will use those configuration to make the quires from WSO2 IS. All the methods which doesn't have "String appId" argument will use the default configuration.

Following JAVA class will give a example to use PEP Proxy. I used a Sample XACML policy hosted in WSO IS. That policy is given below Also,

JAVA Class :

package org.wso2.carbon.identity.entitlement.proxy;

import java.util.HashMap;
import java.util.Map;

public class Test {


    public static void main(String arg[]) throws Exception {

        PEPProxy pepProxy;
        //Initializing the PEP Proxy

        System.setProperty("javax.net.ssl.trustStore", "wso2carbon.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");

        Map<String,Map<String,String>> appToPDPClientConfigMap = new HashMap<String, Map<String,String>>();

        //Configuration to Initialize SOAP Client
        Map<String,String> clientConfigMapSOAP = new HashMap<String, String>();
        clientConfigMapSOAP.put("client", "soap");
        clientConfigMapSOAP.put("serverUrl", "https://localhost:9443/services");
        clientConfigMapSOAP.put("userName", "admin");
        clientConfigMapSOAP.put("password", "admin");
        clientConfigMapSOAP.put("reuseSession", "false");

        appToPDPClientConfigMap.put("SOAP_APP", clientConfigMapSOAP);

        //Configuration to Initialize Basic Authentication Client
        Map<String,String> clientConfigMapBasicAuth = new HashMap<String, String>();
        clientConfigMapBasicAuth.put("client", "basicAuth");
        clientConfigMapBasicAuth.put("serverUrl", "https://localhost:9443/services");
        clientConfigMapBasicAuth.put("userName", "admin");
        clientConfigMapBasicAuth.put("password", "admin");

        appToPDPClientConfigMap.put("BasicAuth_APP", clientConfigMapBasicAuth);

        //Configuration to Initialize Thrift Client
        Map<String,String> clientConfigMapThrift = new HashMap<String, String>();
        clientConfigMapThrift.put("client", "soap");
        clientConfigMapThrift.put("serverUrl", "https://localhost:9443/services");
        clientConfigMapThrift.put("userName", "admin");
        clientConfigMapThrift.put("password", "admin");
        clientConfigMapThrift.put("reuseSession", "false");
        clientConfigMapThrift.put("thriftHost", "localhost");
        clientConfigMapThrift.put("thriftPort", "10500");

        appToPDPClientConfigMap.put("Thrift_App", clientConfigMapThrift);


        PEPProxyConfig config = new PEPProxyConfig(appToPDPClientConfigMap,"SOAP_APP", "Simple", 10000, 100);
        pepProxy = new PEPProxy(config);

        String result = pepProxy.getDecision("admin", "/Entitlement_Sample_WebApp/protected.jsp", "GET", "");
        System.out.println(result);
        result = pepProxy.getDecision("admin", "/Entitlement_Sample_WebApp/protected.jsp", "GET", "", "BasicAuth_APP");
        System.out.println(result);
        result = pepProxy.getDecision("admin", "/Entitlement_Sample_WebApp/protected.jsp", "GET", "", "Thrift_App");
        System.out.println(result);
        boolean bResult = pepProxy.subjectCanActOnResource("urn:oasis:names:tc:xacml:1.0:subject:subject-id", "admin", "GET", "/Entitlement_Sample_WebApp/protected.jsp", "");
        System.out.println(bResult);
    }
}
Samples XACML Policy :

<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"  PolicyId="Entitlement_Filter_Sample_Policy" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable" Version="1.0">
    <Target></Target>
    <Rule Effect="Permit" RuleId="Rule1">
        <Target>
            <AnyOf>
                <AllOf>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">/Entitlement_Sample_WebApp/protected.jsp</AttributeValue>
                        <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
                    </Match>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">GET</AttributeValue>
                        <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
                    </Match>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">admin</AttributeValue>
                        <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
                    </Match>
                </AllOf>
            </AnyOf>
        </Target>
    </Rule>
</Policy>         

To test the PEP Proxy, You can do following steps,
  • Run a WSO2 IS Server 
  • Host the given sample policy
  • Run this Java Class with the dependency jar of PEPProxy. You can get that by building the source given below. That will give you the latest jar of PEPProxy. What you have to do is run mvn clean install in the source folder.
You can find the source of the PEP proxy in http://wso2.org/svn/browse/wso2/carbon/platform/trunk/components/identity/org.wso2.carbon.identity.entitlement.proxy/.I think this post helps you a lot to use IS inf future works.Also contact me if you have any problem. this was a Internship project of me at WSO2.  Please read following to have better understanding about WSO2 IS and related stuff.

 

Sunday, July 22, 2012

Providing XACML Fine Grained Authorization to WebApps : Using WSO2 Identity Server - Part 2

I have discussed about XACML Fine Grained Authorization and how we can use WSO2 IS as a XACML engine in the previous post, Providing XACML Fine Grained Authorization to WebApps : Using WSO2 Identity Server - Part 1 .

So as we know we can use WSO2 Application Server or Apache Tomcat or any other web container to host our web apps. So if there is a requirement to provide authorization to those web apps? That means some one want to allow access to there web apps on a fine grained manner. This has been done in the WSO2 platform. That was a project of mine. So using WSO2 Identity server as the XACML Policy Decision Point (PDP) we can provide fine grained authorization to webapps. This PDP can be access via a web service called Entitlement Service.

So what will the Policy Enforcement Point(PEP) for the webapp authorization ? After having some discussions we thought that a Servlet Filter will be the ideal solution. Any webapp developer can define a servlet filter which they want to use. Also we can use servlet filter in any kind of webapp container.

On that decision we have created a servlet filter which user can use to provide authorization to their web apps. We gave the name Entitlement Servlet Filter to that. It uses a Proxy to communicate with WSO2 Identity Server. The Entitlement PEP Proxy is responsible for following tasks,
  • There is a service in the WSO2 IS called Entitlement Service, that service is used to evaluate XCAML requests.
  • That is a admin service which can be used by the Admin Role.
  • To use that service we have to log in to the IS using AuthenticationAdmin Service.
  • So PEP Proxy log in to the IS as admin, so we can use it's Entitlement Service to evaluate requests coming.
  • We provide following parameters to PEP Proxy to evaluate the request against XACML policies in the WSO2 IS, UserName, ResourceName, Action and Environment. So it queries IS using the provided parameters and gives us the authorization decision.
The following digram shows how the the servlet filter gets the authorization decision,


The next problem is how we should obtain the parameters, UserName, ResourceName, Action and Environment. Exept the user name others we have. Because they are all related tot the web app. How we can get the user name? For that we used J2EE authentication mechanisms,
  • Basic Authentication
  • Client Cert Authentication
  • Digest Authentication
  • Form Authentication
After the authentication we can obtain the username in the the servlet filter. So all the parameters are found now.
As shown in the digram, when a request comes to a particular weapp which has the engaged Entitlement Servlet Filter it obtains the parameters UserName, ResourceName, Action and Environment. Then it initialize the PEP Proxy to communicate with WSO2 IS. After that it send the parameters and get the Entitlement decision. On the provided decision it stop or pass the request which has came to the web app. 

The next critical thing is how the user can engage the Entitlement Servlet Filter. For that we  use the web.xml. The following shows a example web.xml which configures the Entitlement Servlet Filter.


<?xml version="1.0" encoding="UTF-8"?>
<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_2_5.xsd"
         id="WebApp_ID" version="2.5">

    <!-- Sample deployment descriptor configuration for EntitlementFilter -->

    <!-- The scope in which the subject would be available.  Legal values are basicAuth,request-param, request-attribute, session -->
    <context-param>
        <param-name>subjectScope</param-name>
        <param-value>request-param</param-value>
    </context-param>

    <!-- The name of the identifier by which to identify the subject -->
    <context-param>
        <param-name>subjectAttributeName</param-name>
        <param-name>userName</param-name>
    </context-param>

    <!-- The username to perform EntitlementService query-->
    <context-param>
        <param-name>userName</param-name>
        <param-value>admin</param-value>
    </context-param>

    <!-- The password to perform EntitlementService query -->
    <context-param>
        <param-name>password</param-name>
        <param-value>admin</param-value>
    </context-param>

    <!-- The URL to perform EntitlementService query-->
    <context-param>
        <param-name>remoteServiceUrl</param-name>
        <param-value>https://localhost:9443/services</param-value>
    </context-param>

    <!-- EntitlementFilter Settings -->
    <filter>
        <filter-name>EntitlementFilter</filter-name>
        <filter-class>org.wso2.carbon.identity.entitlement.filter.EntitlementFilter</filter-class>

        <!--
  Client class that extends AbstractEntitlementServiceClient. Legal values are basicAuth, soap and thrift.
  Default is 'thrift'.
        -->
        <init-param>
            <param-name>client</param-name>
            <param-value>basicAuth</param-value>
        </init-param>

        <!--
         Decision caching at PEPProxy. Legal values are simple and carbon.This parameter is optional.
         If not specified no caching is done.
        -->
        <init-param>
            <param-name>cacheType</param-name>
            <param-value>simple</param-value>
        </init-param>

        <!--
         Maximum number of cached entries. Legal values are between 0 and 10000 .
         Only works with caching.
        -->
        <init-param>
            <param-name>maxCacheEntries</param-name>
            <param-value>1000</param-value>
        </init-param>

        <!-- Time interval for which cached entry is valid. Only works with simple cache type. -->
        <init-param>
            <param-name>invalidationInterval</param-name>
            <param-value>100000</param-value>
        </init-param>

        <!-- URL ro redirect to if authorization fails -->
        <init-param>
            <param-name>authRedirectUrl</param-name>
            <param-value>/index.jsp</param-value>
        </init-param>

        <!-- Thrift host to be used if using 'thrift' client -->
        <init-param>
            <param-name>thriftHost</param-name>
            <param-value>localhost</param-value>
        </init-param>

        <!-- Thrift port to be used if using 'thrift' client -->
        <init-param>
            <param-name>thriftPort</param-name>
            <param-value>10500</param-value>
        </init-param>
    </filter>

    <!-- Filter mappings used to configure URLs that need to be authorized  -->
    <filter-mapping>
        <filter-name>EntitlementFilter</filter-name>
        <url-pattern>/protected.jsp</url-pattern>
    </filter-mapping>

    <!-- Mandatory mapping that needs to be present to work with PEP cache update authorization-->
    <filter-mapping>
        <filter-name>EntitlementFilter</filter-name>
        <url-pattern>/updateCacheAuth.do</url-pattern>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

    <!-- EntitlementCacheUpdateServlet settings-->
    <servlet>
        <servlet-name>EntitlementCacheUpdateServlet</servlet-name>
        <servlet-class>org.wso2.carbon.identity.entitlement.filter.EntitlementCacheUpdateServlet
        </servlet-class>

        <!-- HTTPS port of the web container used when redirecting request to come over https port for cache update authentication -->
        <init-param>
            <param-name>httpsPort</param-name>
            <param-value>9453</param-value>
        </init-param>

        <!-- Authentication mode for cache update. Legal values are webapp and wso2is -->
        <init-param>
            <param-name>authentication</param-name>
            <param-value>webapp</param-value>
        </init-param>

        <!-- Authentication page used for cache update authentication. Legal values are default and custom -->
        <init-param>
            <param-name>authenticationPage</param-name>
            <param-value>default</param-value>
        </init-param>

        <!-- Authentication page URL used for cache update authentication. Works only with custom for authenticationPage -->
        <init-param>
            <param-name>authenticationPageUrl</param-name>
            <param-value>/updateCache.html</param-value>
        </init-param>
    </servlet>

    <!-- Servlet mapping needed for cache update authentication -->
    <servlet-mapping>
        <servlet-name>EntitlementCacheUpdateServlet</servlet-name>
        <url-pattern>/updateCache.do</url-pattern>
    </servlet-mapping>
</web-app>

Providing XACML Fine Grained Authorization to WebApps : Using WSO2 Identity Server - Part 1

What is XACML Fine Grained Authorization ?

When we talk about a resource ( Here resource is the Webapp hosted in either WSO2 Application Server, Apache Tomcat  etc.) we have to talk about authorization of the users who use those resources. That means some users are authorized to uses the resource and some are not. So what is mean by Fine Grained Authorization ? Traditionally authorization of the user for resource is decided by the users,resource and the action which user does on the resource. But  if we can provided authorization based on user, resource, action user does on resources, environment, time, user's role etc. that is fine grained authorization. We use more details of the scenario to decide the authorization of the user. For a example if there is requirement like this, " This document can be edited by only AndunSLG, who is a Teacher and between 8am to 10am at the school office premises". The given requirement is a fine grained authorization requirement.
To evaluate such requirement against users request, we have to document those fine grained authorization requirements. Those are called Polices. XACML is used to document these kind of polices. We can evaluate user's requirements against these XACML polices using a XACML engine.
We can use WSO2 Identity Server for this requirement. It have a XACML Policy Engine where users can evaluate there requests. Also it provides so many functionalities related to XACML Authorization At the end I have given lot of references where you can learn about XACML.

References,

XACML Policy Language
WSO2 Identity Server

Sunday, July 1, 2012

Resolve dependencies in Apache Ant using Apache Ivy

Most of you have experience that we can use Apache Maven to automate build processes. Also we can use Apache Ant forthe same process. But when we use Maven we can resolve our dependencies of the project easily. The only thing required is adding your dependencies to the pom.xml as given bellow.

<dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>compile</scope>
        </dependency>
</dependencies>

But when use Apache Ant, we have to do some specifics tasks to resolve dependencies in a intelligent manner. Why I say in a intelligent manner
means if we know all the dependencies exactly, we can use following command to download all the jar files needed to our project.
<get src="http://repo1.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar" dest="${ivy.jar.file}" usetimestamp="true"/>
But if don't know all the dependency tree, we are in trouble. So in that case we can use Apache Ivy to resolve all the dependencies. Please look at the given Apache Ant build.xml file.
<project default="compile-all" xmlns:ivy="antlib:org.apache.ivy.ant">
    <property name="classes" value="classes"/>
    <property name="src" value="src"/>
    <property name="ivy.install.version" value="2.0.0-beta1" />
    <property name="ivy.jar.dir" value="${basedir}/ivy" />
    <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" />
    <path id="class.path">
        <pathelement path="${java.class.path}"/>
        <fileset dir="./lib">
            <include name="**"/>
        </fileset>
    </path>
    <target name="clean">
        <delete dir="${classes}"/>
    <delete dir="${lib}"/>
    <delete dir="${ivy}"/>
    </target>
    <target name="init" depends="clean">
        <mkdir dir="${classes}"/>
    </target>
    <!-- #######Downloading and Installing Apache Ivy#######-->
    <target name="download-ivy" unless="skip.download" depends="init">
        <mkdir dir="${ivy.jar.dir}"/>
        <get src="http://repo1.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar" dest="${ivy.jar.file}" usetimestamp="true"/>
    </target>
    <target name="install-ivy" depends="download-ivy" >
        <path id="ivy.lib.path">
            <fileset dir="${ivy.jar.dir}" includes="*.jar"/>
        </path>
        <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
    </target>    
    <!-- ######################################-->
    <!-- ###########Resolving Dependencies Using Ivy######-->
    <target name="getDependency" depends="install-ivy">
        <ivy:retrieve />
    </target> 
    <!-- ######################################-->
    <target name="compile-all" depends="getDependency">
        <javac debug="on" destdir="${classes}">
            <src path="${src}"/>
            <classpath refid="class.path"/>
        </javac>
    </target>       
</project>  
Here in this project we need, Junit and Spring Framework for compile and run the project. To get those jars to our project we use Ivy. First of all we have to get Ivy downloaded. After downloading Ivy we can retrieve our dependencies. Those dependencies have to be specified in file called ivy.xml which exists in the working directory. For this project this is the ivy.xml,
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<info organization="andunslg" module="my_project"/>
    <dependencies>
        <dependency org="junit" name="junit" rev="4.0" transitive="false"/> 
        <dependency org="org.springframework" name="spring-context" rev="3.0.7.RELEASE" transitive="false"/>
        <dependency org="org.springframework" name="spring-core" rev="3.0.7.RELEASE" transitive="false"/>
        <dependency org="org.springframework" name="spring-beans" rev="3.0.7.RELEASE" transitive="false"/>         
    </dependencies>
</ivy-module>
Here you can see that dependencies are specified in our manner ,
<dependency org="junit" name="junit" rev="4.0" transitive="false"/> 
In that org, name, version are very important. Because Ivy use those details to download the jars from the public repo. Also in default Ivy download all the transitive dependencies of the jars. We can stop that by saying transitive="false". Ivy will download all the jars to a called lib in the working directory. After that we can use that in our class path. If you need to find org, name, version of your jars, pleas use this link. http://mvnrepository.com/ In that details are given in this way,
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>3.0.7.RELEASE</version>
</dependency>
Here groupId=org, artifactId=name. So you can create your ivy.xml using those details. Hope this helps you.Contact me for further clarifications. The follwoing shell output show how this build.xml works,

andunslg@andunslg-Dell-System-Vostro-3450:~/temp$ ant
Buildfile: /home/andunslg/temp/build.xml

clean:
   [delete] Deleting directory /home/andunslg/temp/classes

init:
    [mkdir] Created dir: /home/andunslg/temp/classes

download-ivy:
      [get] Getting: http://repo1.maven.org/maven2/org/apache/ivy/ivy/2.0.0-beta1/ivy-2.0.0-beta1.jar
      [get] To: /home/andunslg/temp/ivy/ivy.jar
      [get] Not modified - so not downloaded

install-ivy:

getDependency:
No ivy:settings found for the default reference 'ivy.instance'.  A default instance will be used
no settings file found, using default...
[ivy:retrieve] :: Ivy 2.0.0-beta1 - 20071206070608 :: http://ant.apache.org/ivy/ ::
:: loading settings :: url = jar:file:/home/andunslg/temp/ivy/ivy.jar!/org/apache/ivy/core/settings/ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: wso2#spring;working@andunslg-Dell-System-Vostro-3450
[ivy:retrieve]     confs: [default]
[ivy:retrieve]     found junit#junit;4.0 in public
[ivy:retrieve]     found org.springframework#spring-context;3.0.7.RELEASE in public
[ivy:retrieve]     found org.springframework#spring-core;3.0.7.RELEASE in public
[ivy:retrieve]     found org.springframework#spring-beans;3.0.7.RELEASE in public
[ivy:retrieve] :: resolution report :: resolve 1517ms :: artifacts dl 20ms
    ---------------------------------------------------------------------
    |                  |            modules            ||   artifacts   |
    |       conf       | number| search|dwnlded|evicted|| number|dwnlded|
    ---------------------------------------------------------------------
    |      default     |   4   |   0   |   0   |   0   ||   4   |   0   |
    ---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: wso2#spring
[ivy:retrieve]     confs: [default]
[ivy:retrieve]     0 artifacts copied, 4 already retrieved (0kB/30ms)

compile-all:
    [javac] /home/andunslg/temp/build.xml:39: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
    [javac] Compiling 1 source file to /home/andunslg/temp/classes

BUILD SUCCESSFUL
Total time: 12 seconds
           

Saturday, June 30, 2012

WSDL2Java conversion in Apache Ant using Apache CXF

If you use  Apache Ant to automate your build process, most of the cases this will be a very useful thing to remember. If you want to to generate a Java code using WSDL file this is the way to do it. To do it you need to have Apache CXF as a dependency. Following ant file will gerate a Java code using a given WSDL file.

<project default="compile-all">

    <property name="classes" value="$classes"/>
    <property name="genCode" value="$genCode"/>
    <property name="dependencies" value="$dependencies"/>
    <path id="class.path">
        <fileset dir="${dependencies}">
            <include name="**"/>
        </fileset>
    </path>  
    <target name="init">
        <mkdir dir="${classes}"/>
        <mkdir dir="${genCode}"/>
    </target>
    <target name="cxfWSDLToJava" depends ="init ">
      <echo message="Genarating WSDLToJava"/>    
      <java classname="org.apache.cxf.tools.wsdlto.WSDLToJava" fork="true">
         <arg value="-client"/>
         <arg value="-d"/>
         <arg value="${genCode}"/>
         <arg value="-b"/>
         <arg value="./async_binding.xml"/>
         <arg value="./hello_world_async.wsdl"/>
         <classpath>
        <path refid="class.path"/>
         </classpath>
      </java>
    </target>
    <target name="compile-all" depends="cxfWSDLToJava">
        <javac debug="on" destdir="${classes}">
            <src path="${genCode}"/>
            <classpath refid="class.path"/>
        </javac>
    </target>    
</project> 

This task will do WSDL2Java conversion. You need to have a dependencies directory created with the necessary cxf jars. You can find them here, http://cxf.apache.org/download.html Also if you need other dependencies to compile you have to put those jars there.Also for further customization please visit this url http://cxf.apache.org/docs/wsdl-to-java.html

Tuesday, May 29, 2012

Writing a Apache Axis2 Module

As intern at WSO2 we learn lot about Apache Axis 2, because my team at WSO2 works on a product called Application Server  which is based on Axis2. So we have to play a lot with Axis2. The most interesting thing I have done with Axis2 is extending by writing a module to it. Here I am going to talk about how to do it. I will explain how I did it.

Before read this article about Writing a Module, Better you read these articles to get a better picture about Apache Axis 2 and it's underlining architecture,

What is Apache Axis2 :
http://axis.apache.org/axis2/java/core/

How to write a Apache Axis2 Web Service :
http://wso2.org/library/95

What is a Apache Axis2 Module :
http://axis.apache.org/axis2/java/core/docs/Axis2ArchitectureGuide.html

Also there is a interesting book written by Mr Afkham Azeez and Mr Deepal Jayasinghe. It explain all about Apache Axis2. Please read it to have 100% understanding about Axis 2. The book is Apache Axis2 Web Services, 2nd Edition.

If you have read those articles or had prior knowledge you can understand that a module will add some functionality to the execution chain of axis2 handlers. Single module can have more than one handler. So here in this example I will explain how I wrote my simple axis2 module 2 print the SOAP message content to the info log.

To follow this article you need to have a web services hosted in the simple axis2 server provided by the axis2 distribution. I have add a simple web service to my axis2 server and it is up and running when I start writing the module.  Here are the steps I followed to create and run my web Service.

Definition of My Web Services :

package org.wso2.testws;
public class TestWebService {
    public String sayHello(String name) {
        return "Hello " + name;
    }
    public int add(int x,int y){
        return x+y;
    }
}


My services.xml file :

<service name="TestWebService" >
    <Description>
        This web Service is written for test the functionlity of a AXIS2 Module
    </Description>
    <messageReceivers>
        <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
        <messageReceiver  mep="http://www.w3.org/2004/08/wsdl/in-out"  class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
    </messageReceivers>
    <parameter name="ServiceClass" locked="false">org.wso2.testws.TestWebService</parameter>
</service>


My Folder Stricture :

TestWebService >
      TestWebService.java
      Temp>
           META-INF>
                services.xml
           org>
                wso2>
                     testws>
                          TestWebService.class

After having all these I build my TestWebService.aar file using this command,

jar -cvf TestWebService.aar *

Then I copied that archive to the repository/services folder of the axis2 home folder. Then I run the axis2server.sh script to run the simple server. Then you can see that my new service is successfully deployed.

After that we can start the development of the Axis2 Module. For that purpose I use the Eclipse IDE. Create a new java project in Eclipse and have the following structure in your project.

Here you can see that Axis2 has been added as a library to the project. To do it, right click on the project and got to Build Path > Configure Build Path. There you can find a button called Add Library, click on it and select User Library in the appearing screen. There go to new and add all the jar files in the lib folder in the axis2 home folder.

Then the definition of the TestModule.java is this,

package org.wso2.testa2m;

import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisDescription;
import org.apache.axis2.description.AxisModule;
import org.apache.axis2.modules.Module;
import org.apache.neethi.Assertion;
import org.apache.neethi.Policy;

public class TestModule implements Module{

    public void init(ConfigurationContext configContext, AxisModule module) throws AxisFault {
    }

    public void engageNotify(AxisDescription axisDescription) throws AxisFault {
    }

    public void shutdown(ConfigurationContext configurationContext) throws AxisFault {
    }
    
    public String[] getPolicyNamespaces() {
        return null;    
    }

    public void applyPolicy(Policy policy, AxisDescription axisDescription) throws AxisFault {
    }
           
    public boolean canSupportAssertion(Assertion assertion) {
        return true;
    }
}

The definition of the TestHandler.java is this,

package org.wso2.testa2m;

import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.engine.Handler;
import org.apache.axis2.handlers.AbstractHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class TestHandler extends AbstractHandler implements Handler{
    private static final Log log = LogFactory.getLog(TestHandler.class);
    private String name;

    public String getName() {
        return name;
    }

    public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {
        log.info("The web service "+msgContext.getAxisService().toString()+".");
        log.info("The operation is "+msgContext.getAxisOperation().toString()+".");
        log.info("This is the SOAP envelop : "+msgContext.getEnvelope().toString());
        return InvocationResponse.CONTINUE;        
    }

    public void revoke(MessageContext msgContext) {
        log.info("The web service "+msgContext.getAxisService().toString()+".");
        log.info("The operation is "+msgContext.getAxisOperation().toString()+".");
        log.info("This is the SOAP envelop : "+msgContext.getEnvelope().toString());
    }

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


After doing these, go the eclipse project folder in your machine, then in the TestModule folder you can find a folder called bin which has the generated class files of the project. Go inside it and create a folder called META-INF. In side it create the module.xml file. This is the definition of that file,

<module name="TestModule" class="org.wso2.testa2m.TestModule">
    <InFlow>
        <handler name="InFlowLogHandler" class="org.wso2.testa2m.TestHandler">
            <order phase="TestPhase"/>
        </handler>
    </InFlow>

    <OutFlow>
        <handler name="OutFlowLogHandler" class="org.wso2.testa2m.TestHandler">
            <order phase="TestPhase"/>
        </handler>
    </OutFlow>

    <OutFaultFlow>
        <handler name="FaultOutFlowLogHandler" class="org.wso2.testa2m.TestHandler">
            <order phase="TestPhase"/>
        </handler>
    </OutFaultFlow>

    <InFaultFlow>
        <handler name="FaultInFlowLogHandler" class="org.wso2.testa2m.TestHandler">
            <order phase="TestPhase"/>
        </handler>
    </InFaultFlow>
</module>

After doing that your now in a position to create your module archive file. Go to bin folder of your project using terminal and execute foll wing command,

jar -cvf TestModule.mar *

It will create the archive file needed. Copy it to the repository/modules folder of your axis2 home folder. Now your module is ready to be deployed. Now you have to do some configuration to execute your module. Conceptually Apache Axis2 modules can be executed in two ways,
  • Globally for all the services hosted in Axis2. To do this you have to edit the axis2.xml file
  • Per Service. To do this you have to edit the services.xml file also.
You can find axis2.xml file in the conf folder of axis2 home folder. Edit it like this to add your custom phases to the configuration. In the phases section add the entries which are highlighted to add your definition of custom phase called "TestPhase",

    <!-- ================================================= -->
    <!-- Phases  -->
    <!-- ================================================= -->
    <phaseOrder type="InFlow">
        <!--  System predefined phases       -->
        <phase name="Transport">
            <handler name="RequestURIBasedDispatcher"
                     class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher">
                <order phase="Transport"/>
            </handler>
            <handler name="SOAPActionBasedDispatcher"
                     class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher">
                <order phase="Transport"/>
            </handler>
        </phase>
        <phase name="Addressing">
            <handler name="AddressingBasedDispatcher"
                     class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">
                <order phase="Addressing"/>
            </handler>
        </phase>
        <phase name="Security"/>
    <!-- +++++++Cutome Pahse I have Added+++++++  -->
     <phase name="TestPhase"/>
    <!-- +++++++++++++++++++++++++++++++++++++++ -->
        <phase name="PreDispatch"/>
        <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
            <handler name="RequestURIBasedDispatcher"
                     class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
            <handler name="SOAPActionBasedDispatcher"
                     class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/>
            <handler name="RequestURIOperationDispatcher"
                     class="org.apache.axis2.dispatchers.RequestURIOperationDispatcher"/>
            <handler name="SOAPMessageBodyBasedDispatcher"
                     class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/>
            <handler name="HTTPLocationBasedDispatcher"
                     class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher"/>
            <handler name="GenericProviderDispatcher"
                     class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher"/>
            <handler name="MustUnderstandValidationDispatcher"
                     class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher"/>
        </phase>
        <phase name="RMPhase"/>
        <!--  System predefined phases       -->
        <!--   After Postdispatch phase module author or service author can add any phase he want      -->
        <phase name="OperationInPhase">
            <handler name="MustUnderstandChecker"
                     class="org.apache.axis2.jaxws.dispatchers.MustUnderstandChecker">
                <order phase="OperationInPhase"/>
            </handler>
        </phase>
        <phase name="soapmonitorPhase"/>
    </phaseOrder>
    <phaseOrder type="OutFlow">
        <!--      user can add his own phases to this area  -->
        <phase name="soapmonitorPhase"/>
        <phase name="OperationOutPhase"/>
        <!--system predefined phase-->
        <!--these phase will run irrespective of the service-->
        <phase name="RMPhase"/>
        <phase name="PolicyDetermination"/>
        <phase name="MessageOut"/>
        <phase name="Security"/>
    <!-- +++++++Cutome Pahse I have Added+++++++  -->
     <phase name="TestPhase"/>
    <!-- +++++++++++++++++++++++++++++++++++++++ -->
    </phaseOrder>
    <phaseOrder type="InFaultFlow">
        <phase name="Addressing">
            <handler name="AddressingBasedDispatcher"
                     class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">
                <order phase="Addressing"/>
            </handler>
        </phase>
        <phase name="Security"/>
    <!-- +++++++Cutome Pahse I have Added+++++++  -->
     <phase name="TestPhase"/>
    <!-- +++++++++++++++++++++++++++++++++++++++ -->
        <phase name="PreDispatch"/>
        <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
            <handler name="RequestURIBasedDispatcher"
                     class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
            <handler name="SOAPActionBasedDispatcher"
                     class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/>
            <handler name="RequestURIOperationDispatcher"
                     class="org.apache.axis2.dispatchers.RequestURIOperationDispatcher"/>
            <handler name="SOAPMessageBodyBasedDispatcher"
                     class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/>
            <handler name="HTTPLocationBasedDispatcher"
                     class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher"/>
            <handler name="GenericProviderDispatcher"
                     class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher"/>
            <handler name="MustUnderstandValidationDispatcher"
                     class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher"/>
        </phase>
        <phase name="RMPhase"/>
        <!--      user can add his own phases to this area  -->
        <phase name="OperationInFaultPhase"/>
        <phase name="soapmonitorPhase"/>
    </phaseOrder>
    <phaseOrder type="OutFaultFlow">
        <!--      user can add his own phases to this area  -->
        <phase name="soapmonitorPhase"/>
        <phase name="OperationOutFaultPhase"/>
        <phase name="RMPhase"/>
        <phase name="PolicyDetermination"/>
        <phase name="MessageOut"/>
        <phase name="Security"/>
    <!-- +++++++Cutome Pahse I have Added+++++++  -->
     <phase name="TestPhase"/>
    <!-- +++++++++++++++++++++++++++++++++++++++ -->
    </phaseOrder>

After doing that you are successfully introduced the phase you have created manually, Now it is time to define the execution type of your module,
To excute it globally, add the <module ref="TestModule"/> entry to to the Global section of the axis2.xml.

    <!-- ================================================= -->
    <!-- Global Modules  -->
    <!-- ================================================= -->
    <!-- Comment this to disable Addressing -->
    <module ref="addressing"/>
    <module ref="TestModule"/>
    <!--Configuring module , providing parameters for modules whether they refer or not-->
    <!--<moduleConfig name="addressing">-->
    <!--<parameter name="addressingPara">N/A</parameter>-->
    <!--</moduleConfig>--> 

If you want to add a module specially for a service, add <module ref="TestModule"/> to the service.xml file. Then it will only executed only for that service.
Now your custom module is sucessfully deployed. Now you can start your axis2server again. It will show following log message if your module is successfully loaded. 

[INFO] Deploying module: TestModule - file:/home/andunslg/My_Works/Axis2_Code/modules/distribution/target/axis2-1.7.0-SNAPSHOT/repository/modules/TestModule.mar

After that to check it's functionality use the soapUI. Copy your web service's WSDL files link and create a soapUI project using that. If you are successful you will have a project which looks like this,


Double click on add,  it will show you are SOAP message. Add parameters to the add function and send it. The web service will reply to your message if you have successfully did all the things. If it is this kind of reply will come,


To see what your module to you have to see in to your terminal where you run the axis2server. In that you can see that following log entries are shown. Those are generated by the module you have created.

[INFO] The web service TestWebService.
[INFO] The operation is org.apache.axis2.description.InOutAxisOperation@2ce99681.
[INFO] This is the SOAP envelop : <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tes="http://testws.wso2.org"><soapenv:Body>
      <tes:add>
         <tes:args0>3</tes:args0>
         <tes:args1>2</tes:args1>
      </tes:add>
   </soapenv:Body></soapenv:Envelope>
[INFO] The web service TestWebService.
[INFO] The operation is org.apache.axis2.description.InOutAxisOperation@2ce99681.
[INFO] This is the SOAP envelop : <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:addResponse xmlns:ns="http://testws.wso2.org"><ns:return>5</ns:return></ns:addResponse></soapenv:Body></soapenv:Envelope>


Up to now you have added custom module to AXIS2 to extend it. You can define any task in side your handler definition to o in your module. If you have any problem please contact me.