XFire

Home
Bug/Issue Reporting
Download
FAQ
Get Involved
License
News
Performance
Stack Comparison
Support
Who uses XFire\?
XFire Team

Documentation

Javadocs
Reports
User's Guide
Release Notes

Quicklinks

Aegis Binding
Client
JAXB 2.0
JSR 181 Annotations
Spring

Developers

Developer Space
CVS
Building
Architecture
Interesting Projects
Roadmap
Release Process
JAX\-WS

Steps to implementing WS-Security...

1. Determine how to use the TSIK API
This will be our "hello world" starting point. Figure out how to take a soap document on the file system, encrypt it and decrypt it via the TSIK api so we get an understanding of how to use it.

2. Try it with a document which streams in
Download the code at https://stax2dom.dev.java.net/ and figure out how to use it. You'll need to start with an XMLStreamReader and end up with a document. Pseudocode:

XMLInputFactory factory = XMLInputFactory.getInstance();
XMLStreamReader reader = factory.createXMLStreamReader(inputStreamToFile);

....
// somehow take the reader and create a Document with the above library.
org.w3c.dom.Document doc = ...

3. Create a DocumentXMLStreamReader
In this step we're going to forget about encryption and decryption. After decryption we'll end up with a org.w3c.dom.Document. But XFire expects an XMLStreamReader javadoc. So we need to convert between the two.

public class DocumentXMLStreamReader
    implements XMLStreamReader
{
  public DocumentXMLStreamReader(org.w3c.dom.Document doc)
  {
   ....
  }

  public int next()
  {
    // this would get events as it progressed down the document.
  }
....
}

I've done this before with the XOM xml toolkit. Check out this example. There is also a unit test which shows how to use it.

4. Tie it into XFire
We're going to write a Handler which does the following

  1. takes the incoming XMLStreamReader, reads it into a document
  2. Decrypts the document
  3. Creates another XMLStreamReader from the document

Here's a little pseudo code:

public class WSSecurityInHandler
  extends AbstractHandler
{
  public String getPhase()
  {
    Phase.PARSE;
  }
  public void invoke(MessageContext context)
  {
    Document doc = createDoc(context.getInMessage().getXMLStreamReader);
    decrypt(doc);
    XMLStreamReader reader = createStream(doc);
    context.getInMessage().setXMLStreamReader(reader);
  }
}

A test service:

public class Echo
{
  public String echo(string echo)
  {
    return echo;
  }
}

and a unit test:

public class WSSecurityTest
  extends AbstractXFireTest
{
  Service service;

  public void setUp()
  {
    // Creates a service from the echo class
    service = getServiceFactory().create(Echo.class);

    // Registers it
    getServiceRegistry().register(service);

    // Add in a WS-Security Handler
    service.addInHandler(new WSSecurityHandler());
  }

  public void testService()
  {
    // sends a message to your service. the handler intercepts the document and decrypts
    org.codehaus.yom.Document response = 
      invokeService("Echo", "/encrypted/document/on/the/classpath.xml");

    // prints the response to System.out
    printNode(response);

    // Checks to make sure we get the echo'd response
    addNamespace("e", service.getServiceInfo().getName().getNamespace());
    assertValid("//e:echoResponse", response);
  }
}

The "/encrypted/document/on/the/classpath.xml" needs to be an encrypted version of this document which the WS-SecurityHandler can understand:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
 <env:Body>
  <m:echo xmlns:m="NAMESPACE">
   <m:in0>Yo Yo</m:in0>
  </m:echo>
 </env:Body>
</env:Envelope>

where NAMESPACE is the namespace of your service. The namespace is constructed from the pacakge name. You can easily view this by adding a

System.out.println(service.getServiceInfo().getName().getNamespace());

to the above test.