WSS4J Tutorial revisit

While reading the WSS4J - Axis Deployment Tutorial I found it somewhat lacking. Also in later versions of Axis it seems that the StockQuoteService has been changed.

So here is a reworked version.

Prerequisties

This tutorial was performed on a Linux machine with Java 1.6.0_01-b06.

Installing WSS4J

  1. Install Apache Tomcat
    1. Unpack the Apache Tomcat archive. Below this folder will be called $CATALINA_HOME
    2. Make sure the environment variable $JAVA_HOME is set correctly.
  2. Install Axis
    1. Unpack the Axis archive
    2. Copy the axis folder from webapps into $CATALINA_HOME/webapps
  3. Install WSS4J and XML Security
    1. Unpack the WSS4J archive and copy wss4j.jar into $CATALINA_HOME/axis/WEB-INF/lib
    2. Unpack the XML Security archive and copy xmlsec-1.4.3.jar into $CATALINA_HOME/axis/WEB-INF/lib renaming it to xmlsec.jar
  4. Start up Apache Tomcat by running the startup.sh command in $CATALINA_HOME/bin
  5. Verify the installation by accessing the Axis Happiness Page. It should now list the XML Security API under Optional Components.

Creating and deploying the initial service

This tutorial will reuse the StockQuoteService that ships in the Axis sample folder. However this service tries to look up a real stock quote from a external service, located at services.xmethods.net, that doesn't exists any more. This means that the only symbol we can look up a quote for is XXX.

Compiling and deploying the sample

Go to the unpacked Axis folder and in under samples/stock.
Compile all code using ant. The out put folder is under the Axis folder build/classes.

~axis-1_4/samples/stock$ ant
Buildfile: build.xml

axis-clover-setenv:

axis-clover-setup:

axis-xmlbeans-setenv:

axis-xmlbeans-setup:

setenv:

copy:

compile:
[javac] Compiling 6 source files to ~/axis-1_4/build/classes

BUILD SUCCESSFUL
Total time: 1 second

To deploy the sample service first copy the class files to $CATALINA_HOME/webapps/axis/WEB-INF/classes/


~axis-1_4/samples/stock$ cp -r ../../build/classes/samples $CATALINA_HOME/webapps/axis/WEB-INF/classes

Then edit the template deploy.wsdd to match the one below.

deploy.wsdd

Now deploy using Axis Admin Client.

java -cp $AXISCLASSPATH org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService deploy.wsdd

undeploy.wsdd

Creating the client

Adding usertoken security

New deploy.wsdd

Programmatically setting PWCallback


package samples.stock.client;

import java.rmi.RemoteException;
import java.rmi.Remote;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Stub;
import org.apache.ws.security.message.token.*;
import org.apache.ws.security.handler.*;
import org.apache.ws.security.message.token.*;
import org.apache.ws.security.*;
import org.apache.axis.EngineConfiguration;
import org.apache.axis.Handler;
import org.apache.axis.SimpleChain;
import org.apache.axis.SimpleTargetedChain;
import org.apache.axis.client.Stub;
import org.apache.axis.configuration.SimpleProvider;
import org.apache.axis.transport.http.HTTPSender;
import org.apache.axis.transport.http.HTTPTransport;
import org.apache.ws.axis.security.WSDoAllSender;
import org.apache.ws.security.handler.WSHandlerConstants;

public class StockQuoteServiceClient {
public StockQuoteServiceClient() {
}
public static void main(String[] args) throws ServiceException, RemoteException {
if (args.length == 0) {
System.out.println("Usage:\njava StockQuoteServiceClient [symbol]");
return;
}

SimpleProvider clientConfig = new SimpleProvider();
Handler outHandler = new WSDoAllSender();
outHandler.setOption(WSHandlerConstants.ACTION,
WSHandlerConstants.USERNAME_TOKEN);
outHandler.setOption(WSHandlerConstants.USER, "wss4j");
outHandler.setOption("passwordType", "PasswordText");
SimpleChain reqHandler = new SimpleChain();
reqHandler.addHandler(outHandler);
Handler pivot=(Handler)new HTTPSender();
Handler transport=new SimpleTargetedChain(reqHandler, pivot, null);
clientConfig.deployTransport(HTTPTransport.DEFAULT_TRANSPORT_NAME,
transport);

StockQuoteServiceService locator = new StockQuoteServiceServiceLocator(clientConfig);
Remote remote = locator.getPort(StockQuoteService.class);
Stub axisPort = (Stub)remote;
axisPort._setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, "samples.stock.client.PWCallback");

StockQuoteService service = (GetQuoteSoapBindingStub)axisPort; /* locator.getGetQuote(); */

float quote = service.getQuote(args[0]);
System.out.println("stock quote service returned " + args[0] + ": " + quote);
}
}