WS-Security, Axis2 and Rampart#

One of the things that I don’t like about Java is that the community is not using the same foundational libraries. For example, there is not a standard J2EE application server. Instead there is a specification and hundreds of vendors. As a result, everyone seems to be using a different implementation of a specification, and thus finding answers to questions is a lot harder because the user community is spread across many many implementations.

Recently, I had to call a web service which was protected by WS-Security UsernameToken. I was able to quickly call the service with Axis 1.1 and WSS4J but when I tried to use Axis2 and Rampart I ran into exception after exception. After several days of struggling, I was eventually able to create a web service client that created the proper soap message.

This blog contains a step by step procedure to create a web service client to a web service which is protected by ws-security UsernameToken.

I am assuming that you have already deployed the web service which is protected by ws-security and that you simply want to call the service using Axis2 version 1.3 and Rampart 1.3. Here are the steps:

1) Download Axis2 version 1.3 from http://ws.apache.org/axis2/

2) Download Rampart 1.3 from http://ws.apache.org/axis2/modules/index.html

3) Add Axis2 JARs to your client application classpath--all JARs from the Axis2 distribution lib directory.

3) Add the Rampart jars to your client application classpath--all jars from the Rampart distribution lib directory.

4) Create a proxy to the web service that is protected by ws-security--using the WSDL2Java tool or batch file.

5) Create an Axis2 client-configuration file which engages rampart and which has the ws-security parameter. Place this file within your client application project. For example, the standard is to create a folder called "conf" for this file.

Here is an example file:

 

<axisconfig name="AxisJava2.0">

<!-- engage rampart -->

<module ref="rampart" />

 

<!-- ws-security parameters: UsernameToken and PasswordText -->

<parameter name="OutflowSecurity">

<action>

<items>UsernameToken</items>

<user>myusername</user>

<passwordCallbackClass>com.mycomp.test.PWCBHandler</passwordCallbackClass>

<passwordType>PasswordText</passwordType>

</action>

</parameter>

<!-- ================================================= -->

<!-- Parameters -->

<!-- ================================================= -->

<parameter name="hotdeployment">true</parameter>

<parameter name="hotupdate">false</parameter>

<parameter name="enableMTOM">false</parameter>

<parameter name="enableSwA">false</parameter>

<!--Uncomment if you want to enable file caching for attachments -->

<!--parameter name="cacheAttachments">true</parameter>

<parameter name="attachmentDIR"></parameter>

<parameter name="sizeThreshold">4000</parameter-->

<!--This will give out the timout of the configuration contexts, in seconds-->

<parameter name="ConfigContextTimeoutInterval">30</parameter>

<!--During a fault, stacktrace can be sent with the fault message. The following flag will control -->

<!--that behaviour.-->

<parameter name="sendStacktraceDetailsWithFaults">false</parameter>

<parameter name="DrillDownToRootCauseForFaultReason">false</parameter>

<parameter name="userName">admin</parameter>

<parameter name="password">axis2</parameter>

<!--Set the flag to true if you want to enable transport level session mangment-->

<parameter name="manageTransportSession">false</parameter>

<!-- Following parameter will completely disable REST handling in Axis2-->

<parameter name="disableREST" locked="true">false</parameter>

<!-- ================================================= -->

<!-- Message Receivers -->

<!-- ================================================= -->

<!--This is the Deafult Message Receiver for the system , if you want to have MessageReceivers for -->

<!--all the other MEP implement it and add the correct entry to here , so that you can refer from-->

<!--any operation -->

<!--Note : You can ovride this for particular service by adding the same element with your requirement-->

<messageReceivers>

<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"

class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>

<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"

class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>

</messageReceivers>

<!-- ================================================= -->

<!-- Message Formatter -->

<!-- ================================================= -->

<!--Following content type to message formatter mapping can be used to implement support for different message -->

<!--format serialization in Axis2. These message formats are expected to be resolved based on the content type. -->

<messageFormatters>

<messageFormatter contentType="application/x-www-form-urlencoded"

class="org.apache.axis2.transport.http.XFormURLEncodedFormatter"/>

<messageFormatter contentType="application/xml"

class="org.apache.axis2.transport.http.ApplicationXMLFormatter"/>

<messageFormatter contentType="text/xml"

class="org.apache.axis2.transport.http.ApplicationXMLFormatter"/>

<messageFormatter contentType="application/echo+xml"

class="org.apache.axis2.transport.http.ApplicationXMLFormatter"/>

</messageFormatters>

<!-- ================================================= -->

<!-- Transport Ins -->

<!-- ================================================= -->

<transportReceiver name="http"

class="org.apache.axis2.transport.http.SimpleHTTPServer">

<parameter name="port">6060</parameter>

</transportReceiver>

<!--Uncomment this and configure as appropriate for JMS transport support, after setting up your JMS environment (e.g. ActiveMQ)

<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">

<parameter name="myTopicConnectionFactory">

<parameter name="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>

<parameter name="java.naming.provider.url">tcp://localhost:61616</parameter>

<parameter name="transport.jms.ConnectionFactoryJNDIName">TopicConnectionFactory</parameter>

</parameter>

<parameter name="myQueueConnectionFactory">

<parameter name="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>

<parameter name="java.naming.provider.url">tcp://localhost:61616</parameter>

<parameter name="transport.jms.ConnectionFactoryJNDIName">QueueConnectionFactory</parameter>

</parameter>

<parameter name="default">

<parameter name="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>

<parameter name="java.naming.provider.url">tcp://localhost:61616</parameter>

<parameter name="transport.jms.ConnectionFactoryJNDIName">QueueConnectionFactory</parameter>

</parameter>

</transportReceiver>-->

<!-- ================================================= -->

<!-- Transport Outs -->

<!-- ================================================= -->

<transportSender name="tcp"

class="org.apache.axis2.transport.tcp.TCPTransportSender"/>

<transportSender name="local"

class="org.apache.axis2.transport.local.LocalTransportSender"/>

<transportSender name="http"

class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">

<parameter name="PROTOCOL">HTTP/1.1</parameter>

<parameter name="Transfer-Encoding">chunked</parameter>

<!-- If following is set to 'true', optional action part of the Content-Type will not be added to the SOAP 1.2 messages -->

<!-- <parameter name="OmitSOAP12Action">true</parameter> -->

</transportSender>

<transportSender name="https"

class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">

<parameter name="PROTOCOL">HTTP/1.1</parameter>

<parameter name="Transfer-Encoding">chunked</parameter>

</transportSender>

<!-- ================================================= -->

<!-- Global Modules -->

<!-- ================================================= -->

<!-- Comment this to disable Addressing -->

<module ref="addressing"/>

<!--Configuring module , providing parameters for modules whether they refer or not-->

<!--<moduleConfig name="addressing">-->

<!--<parameter name="addressingPara">N/A</parameter>-->

<!--</moduleConfig>-->

<!-- ================================================= -->

<!-- Clustering -->

<!-- ================================================= -->

<!-- Configure and uncomment following for preparing Axis2 to a clustered environment -->

<!--

<cluster class="org.apache.axis2.cluster.tribes.TribesClusterManager">

<parameter name="param1">value1</parameter>

</cluster>

-->

<!-- ================================================= -->

<!-- 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"/>

<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"/>

</phase>

<phase name="RMPhase"/>

<!-- System predefined phases -->

<!-- After Postdispatch phase module author or service author can add any phase he want -->

<phase name="OperationInPhase"/>

<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"/>

</phaseOrder>

<phaseOrder type="InFaultFlow">

<phase name="Addressing">

<handler name="AddressingBasedDispatcher"

class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">

<order phase="Addressing"/>

</handler>

</phase>

<phase name="Security"/>

<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"/>

</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"/>

</phaseOrder>

</axisconfig>

 

The configuration file above is a typical client config file with the rampart and ws-security configuration.

6) When calling the web service through the web service stub, you'll have to give Axis the path to the Axis configuration file above. Moreover, for Axis to engage Rampart, you'll have to give Axis the path to the Axis respository folder. The repository folder needs to have a subdirectory called "modules" and within that directory, the Rampart 1.3 "mar" file has to exist. Therefore, create a folder somewhere within your project called "repository". Then create a subdirectory called "modules". Finally, copy the "rampart-1.3.mar" file from the Rampart distributable.

7) Now you are ready to make a service call. First create an instance of a custom configuration passing in the repository path and the axis configuration file path.

ConfigurationContext cxt =

ConfigurationContextFactory.createConfigurationContextFromFileSystem("c:\\folderpath\\repository","c:\\path_to_axis_config_file.xml");

8) Create a stub with the custom axis configuration instance.

HelloServiceStub stub = new HelloServiceStub(ctx,"http://localhost:8080/services/HelloService");

HelloServiceStub.Echo echoReq = new HelloServiceStub.Echo();

System.out.println("calling service...");

HelloServiceStub.EchoResponse resp = stub.echo(echoReq);

System.out.println("done calling service...");

The key to the whole process was ConfigurationContextFactory.createConfigurationContextFromFileSystem. When calling this method, you need to make sure you pass the correct repository path and a proper Axis2 client configuration file. The path to the repository has to have a sub directory called "modules" and that has to contain the rampart "mar" file. If this is not correct, then Axis2 will not be able to engage Rampart.

10/9/2007 8:00:29 AM (Eastern Daylight Time, UTC-04:00) #    Comments [4]  |  Trackback

 

All content © 2009, Sayed Y. Hashimi
On this page
This site
Calendar
<January 2009>
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567
Archives
Sitemap
Blogroll OPML
Disclaimer

Powered by: newtelligence dasBlog 1.8.5223.2

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Send mail to the author(s) E-mail

Theme design by Jelle Druyts