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
- Apache Tomcat 6.0.14
- Axis 1.4
- WSS4J 1.5.9
- XML Security 1.4.3
This tutorial was performed on a Linux machine with Java 1.6.0_01-b06.
Installing WSS4J
- Install Apache Tomcat
- Unpack the Apache Tomcat archive. Below this folder will be called $CATALINA_HOME
- Make sure the environment variable $JAVA_HOME is set correctly.
- Install Axis
- Unpack the Axis archive
- Copy the axis folder from webapps into $CATALINA_HOME/webapps
- Install WSS4J and XML Security
- Unpack the WSS4J archive and copy wss4j.jar into $CATALINA_HOME/axis/WEB-INF/lib
- Unpack the XML Security archive and copy xmlsec-1.4.3.jar into $CATALINA_HOME/axis/WEB-INF/lib renaming it to xmlsec.jar
- Start up Apache Tomcat by running the startup.sh command in $CATALINA_HOME/bin
- 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);
}
}