You are on page 1of 38

Understanding Web Services specifications, Part

4: WS-Security
Skill Level: Intermediate

Nicholas Chase (ibmquestions@nicholaschase.com)


Freelance writer
Backstop Media

22 Aug 2006

There are few (if any) enterprise-level systems that don't require one form of security
or another. In Web services, this process is more complicated than in other arenas
because of the distributed, stateless nature of the beast. This tutorial, Part 4 of the
Understanding Web services specifications series, explains the concepts behind
WS-Security and related standards such as XML Signature, which combine to make
security in the Web services world not just possible, but practical.

Section 1. Before you start


In this tutorial you'll learn about Web Services Security, or WS-Security. It is for
developers who wish to expose their own services in an environment that requires
protection of messages from being tampered or read in transit, or in situations in
which the sender must be positively identified. The term "WS-Security" is usually
used to refer to a group of specifications that handle encryption and digital
signatures, enabling you to create a secure application.

In order to follow along with this tutorial, you should have a basic understanding of
SOAP, which you can achieve by reading Part 1 of this tutorial series, and by
extension, you need a basic understanding of XML. SOAP is programming-language
agnostic, but the samples in this tutorial use Java ™ and the Apache Axis2 project.
The concepts, however, apply to any programming language and environment.

About this series


This tutorial series teaches the basic concepts of Web services by following the
exploits of the fictional newspaper, The Daily Moon, as the staff uses Web services
to create a workflow system to increase productivity in the midst of much change.

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 1 of 38
developerWorks® ibm.com/developerWorks

Part 1 explained the basic concepts behind Web services and showed how to use
SOAP, the specification that underlies most of what is to come, connecting the
classifieds department with the Content Management System.

Part 2 takes things a step further, explaining how to use Web Services Description
Language (WSDL) to define the messages produced at expected by Web service,
enabling the team to more easily create services and the clients that connect to
them.

Part 3 finds the team with a number of services in place and a desire to locate them
easily. In response, Universal Description, Discovery and Integration (UDDI)
provides a searchable registry of available services at a way to publicize their own
services to others.

Now in Part 4, Rudy, publisher of the The Daily Moon, has decided that the paper
needs to institute better security procedures for Web services that access their
internal systems.

In Part 5, WS-Policy, we will look at the changes the teams need to make in order to
access those newly secured services.

Interoperability will be the key word in Part 6, as services from several different
implementations must be accessed from a single system. Part 6 will also cover the
requirements and tests involved in WS-I certification.

Finally, Part 7 will show how to use Business Process Execution Language
(WS-BPEL) to create complex applications from individual services.

Now let's look at what this tutorial covers in a bit more detail.

About this tutorial


In this tutorial, you will follow along as the The Daily Moon newspaper team uses the
WS-Security specifications to secure one of the Web services described thus far in
the series.

In the course of this tutorial, you will learn:

• What WS-Security is
• The difference between symmetric and asymmetric encryption
• The difference between signatures and encryption
• The effect of security on SOAP messages
• How to secure a SOAP web service using Axis2
Before we get started, you'll need a few tools.

WS-Security
Page 2 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

Prerequisites
Much of this tutorial is conceptual, but in order to follow along with the code that
creates the SOAP messages, you will need to have the following software available
and installed:

We will demonstrate the installation and use of Apache Geronimo, which is also the
basis for IBM's WebSphere Community Edition. You can also use other application
servers such as WebSphere application server. You can download Apache
Geronimo. For more information on installing Geronimo, see Part 1 of this tutorial
series.

You will be using Apache Axis2, which contains implementations of various


SOAP-related APIs to make your life significantly easier. You can download Apache
Axis2 from Apache.org. This tutorial uses version 0.94, but later versions should
work.

Apache Axis2 Rampart module -- Security for the Axis2 Web services engine is
provided through the Rampart module, which is not included in the default
installation. Download this module from the Apache Download Mirrors.

Apache WSS4J -- Although Axis itself will use Rampart, at some point you will need
to reference the WSS4J classes direction. Download the WSS4J package.

Java 2 Standard Edition version 1.4.2 or higher -- All of these tools are Java-based,
as are the services and clients you'll build in this tutorial. Download the J2SE SDK.

TCPMon (optional) -- It's always easier to understand what's going on in a web


service application when you can actually see the messages. Download the TCP
Monitor so you can see the messages coming to and from the Web service.

GnuPG (optional) -- All of the message signing we'll be doing is covered by Axis2
and by Java itself, but if you want to play with signing individual documents, as we'll
briefly demonstrate, download GnuPG.

You'll also need a Web browser and a text editor.

Section 2. Overview
Before we talk about securing a service, it's useful to know exactly what pieces
make up that service to know what has to be done.

The story so far

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 3 of 38
developerWorks® ibm.com/developerWorks

This tutorial series has followed the exploits of the staff of the Daily Moon
newspaper, which has discovered a new way of working in the form of Web
services. It all started in the classifieds department, which decided to enable others
to access its systems through the use of SOAP messages -- XML messages that
can be sent over HTTP.

For example, a request for the number of classified ads in the "for sale" subcategory
might look like Listing 1.

Listing 1. A sample SOAP message


<?xml version='1.0' ?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope">
<env:Header>
</env:Header>
<env:Body>
<cms:getNumberOfArticles xmlns:cms="http://www.daily-moon.com/cms">
<cms:category>classifieds</cms:category>
<cms:subcategory>forsale</cms:subcategory>
</cms:getNumberOfArticles>
</env:Body>
</env:Envelope>

The overall message is called the Envelope, the contents of which consist of the
Header and the Body. The Header contains information about the message itself,
such as routing information, or information intended to be processed by "SOAP
intermediaries", or services between the sender and the ultimate receiver, who may
process the message. (In this case, see any of those headers, but that's where our
security information is going to go.) The Body of the message includes the
"payload", which includes the actual data to be passed to the Web service.

In this case, the payload is the getNumberOfArticles element and its contents.

Gene and Frances, from the newspaper's IT department, have put together a system
for serving Web services requests, as well as the infrastructure for discovering and
automatically creating clients for the services. Now the newspaper's publisher, Rudy,
is insisting that they find a way to prevent unauthorized access to these systems.

The need for security


The basic SOAP specification does not provide for securing messages, leaving that
task for extended specifications. The trouble lies in the nature of a Web services
application. In most cases, we are dealing with SOAP over HTTP, which means that
each message has to travel through one or more intermediate nodes, any one of
which can read and/or alter a message. And that's assuming that the SOAP request
itself was a direct one. In some cases, SOAP messages are specifically designed to
travel through more than one node before arriving at their final destination.

The end result is that we need a way to prevent someone other than the intended
receiver from reading sensitive information, in order to prevent eavesdropping. We
also need a way to prevent someone other than the intended sender from sending
messages, in order to prevent unauthorized access.

WS-Security
Page 4 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

The SOAP specification provides a means for adding security information -- we add
information to an Envelope's Header element -- but does not specify what that
information should be. To take care of that, we need WS-Security.

The pieces of WS-Security


There are three major problems involved in securing SOAP message exchanges,
and WS-Security provides answers for all of them, but not directly. It is, in fact, a
specification that talks not about how to protect the message, but how to let the
receiver know how you've protected the message. To do the actual protecting,
WS-Security references additional specifications. Let's look at how that works.

The first problem is to identify and authenticate the client. Because there are a lot of
different ways to do create security tokens, WS-Security does not specify any
particular means, but rather defines how different security tokens should be
transferred within SOAP messages. In other words, it lets the receiver know how to
extract security tokens from the message for processing.

The second problem is ensuring integrity of the message. WS-Security uses digital
signatures for that, employing the XML Signature specification rather than inventing
something new. XML Signature is a W3C recommendation that provides a
mechanism for digitally signing XML documents.

The third problem is keeping the message safe from eavesdropping while it's in
transit. Once again, WS-Security employs another W3C standard, this time XML
Encryption, which provides a mechanism to encrypt XML documents.

In this tutorial, we'll see how using these standards affects the actual SOAP
messages used, as Gene and Frances work to secure the existing Classifieds'
service.

The current service


Before we look at making changes, it's useful to see where Gene and Frances are
starting out. The Classifieds' service is implemented using Axis2, which means that
it's contained in an *.aar file. The CMSService.aar file consists of three files, as
shown in Listing 2.

Listing 2. The contents of the original service


CMSService.class
meta-inf/Manifest.MF
meta-inf/services.xml

The class itself is straightforward, taking in a SOAP message that lists a category
and returning a SOAP message that includes the number of ads for that category. It
performs this function as defined by the services.xml file (see Listing 3).

Listing 3. The original services.xml file

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 5 of 38
developerWorks® ibm.com/developerWorks

<service name="CMSService">
<description>
This is a sample Web Service for the newspaper's
Content Managment System.
</description>
<parameter name="ServiceClass"
locked="false">CMSService</parameter>
<operation name="getNumberOfArticles">
<messageReceiver class=
"org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>

Securing the service involves touching only the services.xml file; Gene and Frances
won't have to touch the actual Java class at all.

The current client


The client itself is pretty straightforward, and simply makes and displays the request,
as shown in Listing 4:

Listing 4. The original client class


import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
public class ClassifiedClient {
private static EndpointReference targetEPR =
new EndpointReference(
"http://localhost:8888/axis2/services/CMSService");
public static OMElement getNumOfArticlesOMElement() {
SOAPFactory fac = OMAbstractFactory.getSOAP12Factory();
OMNamespace omNs = fac.createOMNamespace(
"http://daily-moon.com/cms", "cms");
OMElement method = fac.createOMElement("getNumberOfArticles",
omNs);
OMElement value = fac.createOMElement("category", omNs);
value.addChild(fac.createOMText(value, "classifieds"));
method.addChild(value);
return method;
}
public static void main(String[] args) {
try {
OMElement payload =
ClassifiedClient.getNumOfArticlesOMElement();
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
OMElement result = sender.sendReceive(payload);

WS-Security
Page 6 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

String response = result.getText();


System.out.println("There are "+response+
" classifieds at the moment.");
} catch (Exception e) {
System.out.println(e.toString());
}
}
}

Note that Gene has changed the endpoint port to 8888, rather than 8080, the port on
which Geronimo is listening. He's done that in order to insert an additional step so
that he can see the messages flying back and forth.

Seeing the messages


To see the actual SOAP messages, download TCPMon from
http://ws.apache.org/commons/tcpmon/download.cgi. (Yes, Axis2 comes with
SOAPMonitor, but Gene discovered the hard way that aside from the hassle in
setting things up, it shows the SOAP but not necessarily the raw messages, which
we'll specifically want to see.)

After downloading, decompress the application and run the


tcpmon-1.0-bin\build\tcpmon.bat file. Click the Admin tab and create a new
listener, as seen in Figure 1.

Figure 1. The TCPMon Admin tab

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 7 of 38
developerWorks® ibm.com/developerWorks

Choose 8888 as the port to listen to, and specify 8080 as the target point, so that
TCPMon sits between the client and the server. Click Add, and then click the Port
8888 tab. Click the XML Format checkbox. Now when Frances executes the client,
Gene can see the request and the response, as in Figure 2.

Figure 2. The original request and response

WS-Security
Page 8 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

Before moving on, let's take a quick look at the actual messages, so we can see
what changes.

The messages
The messages themselves are very straightforward. The request, as seen in Listing
5, simply asks for the number of classified ads in the system:

Listing 5. The original request


<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header />
<soapenv:Body>
<cms:getNumberOfArticles
xmlns:cms="http://daily-moon.com/cms">
<cms:category>classifieds</cms:category>

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 9 of 38
developerWorks® ibm.com/developerWorks

</cms:getNumberOfArticles>
</soapenv:Body>
</soapenv:Envelope>

The response is equally straightforward, as you can see in Listing 6:


Listing 6: The original response
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv=
"http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header />
<soapenv:Body>
<resp:numberOfArcticles
xmlns:resp="http://daily-moon.com/cms/"
xmlns:tns="http://ws.apache.org/axis2"
>42</resp:numberOfArcticles>
</soapenv:Body>
</soapenv:Envelope>

In both of these messages, Frances will place additional information in the Header
element for the server (or the client) to process.

At the moment, anyone can send a request to the service and get a response, and
that's what makes Rudy nervous. He wants the service set up so that only
authorized users can get information, and so that competitors can't intercept the
information. Rudy figures that this is a good proof-of-concept system. He's really
more worried about more complex systems, such as those that add content or
access the accounting system. But the concepts are the same.

To provide that security, Gene and Frances need to use encryption and its related
technology, signatures.

Section 3. Encryption and signatures


The majority of security measures involve one form of encryption or another, or
encryption worked into a digital signature, so before Frances let's Gene start
mucking with the service's security configuration, she wants to make sure they
understand what they're dealing with.

Types of encryption
Encryption is the process of obscuring information to make it unreadable without
special knowledge. History has known many different types of encryption. Modern
encryption usually is a well-defined sequence of transformations applied to a
message and some form of "key". The result is unreadable gibberish. Decryption is a
reverse process and also involves a key, so by keeping the key secret one can be
reasonable sure no one else can read encrypted message. Modern encryption
methods can be classified according to whether they use one or two keys.

WS-Security
Page 10 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

In a symmetric key algorithm (for example, DES), the sender and receiver must have
a shared key set up in advance and kept secret from all other parties; the sender
uses this key for encryption, and the receiver uses the same key for decryption. In
this case, the key itself is unimportant, except that it should be known by the two
parties involved, and only those two parties.

In an asymmetric key algorithm (such as RSA), there are two separate keys: a public
key is published and well-known to belong to a particular individual (or organization),
while a corresponding private key is kept secret. A message encrypted by the public
key can only by decrypted by the public key, so anyone can send a private message
to a particular individual. But the reverse is also true, so a message that can be
decrypted by an individual's public key must have been sent by that individual. We'll
see how this comes into play in encrypting and signing SOAP messages

Encrypting a file
Gene decides to start by seeing how the actual message text is affected by
encryption. He starts with a text file, msg.txt, consisting of single line, as you can see
in Listing 7.

Listing 7. The target text


Hello, world!

To make things simple, he uses the free GnuPG program, executing the command
shown in Listing 8.

Listing 8. The encryption command


gpg.exe -c -a --cipher-algo 3DES msg.txt

This command causes the program to use the symmetric key algorithm 3DES with to
encrypt the file. The program asks for passphrase, which Gene enters as
"password", and then produces the file msg.txt.asc. You can see the contents of this
file in Listing 9.

Listing 9. The encrypted file


-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.2.2 (MingW32)
jA0EAgMCqFjZXeujyOJgySoKQ2qhpCpGERKpFn0iKms4kwjpI51BLcoTyH4p61YJ
kDAiRMbC6PfCBmg=
=G4EN
-----END PGP MESSAGE-----

Certainly nobody would guess the original text from that! Encouraged, Gene moves
on to look at the issue of digital signatures.

How signatures work

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 11 of 38
developerWorks® ibm.com/developerWorks

Digital signatures use encryption techniques, but the purpose of signing is different.
Rather than obscuring the message, a signature gives the receiver confidence in two
pieces of information: the sender of the message, and the message itself.

It works like this. The sender encrypts the message with his or her private key. This
"signature" is then sent to the recipient, along with original message. The recipient
tries to verify the signature, which means decrypting signature with the sender's
public key, and comparing the results to the original message. If this process is
successful, the recipient can be sure only the sender can be the originator of the
message, because nobody except the sender has his or her private key. What's
more, if the original message had changed in transit, the decrypted signature
wouldn't match it, so successful signature verification also means that the message
hasn't been tampered with.

Usually, instead of signing the whole message, the sender calculates a "digest" of
the message (using a cryptographic hash function), signs that, and passes that
along with the unencrypted message. The receiver calculates the digest of the
received message and compares it to the decrypted digest of the signature. This
provides the same effect without having to essentially double the size of each
message. (It also cuts down on processing time to create and verify the signatures.)

Signing a file
Emboldened, Gene decides to see this in action. His intention is to digitally sign the
msg.txt file he'd previously encrypted. Because it makes signing a file simple, he'll
use the same GnuPG software, even though he'll later use a different technique to
create the keys used by the actual application.

The first step is to create the key pair using the command in Listing 10.

Listing 10. Generating a key pair


gpg.exe --gen-key

The program asks a lot of question about the key, such as Gene' name, email, and
so on. He settles on the default key parameters (the DSA algorithm and the 2048 bit
key length), and supplies the name "Jon Dow". This operation stores the keys in a
keystore file in Gene's home folder.

Now he can sign the message. He uses the command shown in Listing 11.

Listing 11. Signing the document


gpg.exe --clearsign -u "Jon Dow" msg.txt

This time, the program asks for the password associated with "Jon Dow"'s private
key, then produces the msg.txt.asc file, as shown in Listing 12.

Listing 12. The signed document


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

WS-Security
Page 12 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

Hello, world!
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (MingW32)
iD8DBQFEhftF06oTl3UESDQRArHsAJ0bE2qUEeVb5IDz4gQuRCgOes6v7gCfQhbJ
l356yO+YTkJUJZx4KoTTzok=
=ld3Y
-----END PGP SIGNATURE-----

A person receiving this message would know to decrypt the signature using "Jon
Dow"'s public key, hash the unencrypted message (using SHA1), and compare the
two.

Now that they understand how encryption and signatures work, Gene and Frances
are ready to move on to securing the actual service.

Section 4. Securing the service


Securing the service involves a number of steps that must take place before the first
secure message can be sent, and while none of them are specific to the actual
WS-Security specification (rather than the software the team is using to generate the
messages), these steps are crucial, and will, in one form or another, take place for
any WS-Security installation.

Generating the keystore


Now that he's seen signatures and encryption in action, Gene needs to start
preparing the team's own installation. He needs to start by creating the keystore,
which will include all of the private key-public key pairs that may be needed. To do
that, he'll use the keytool application that comes with the JDK.

To create a new key and generate a keystore, he executes the following commands,
as seen in Listing 13.

Listing 13. Creating a key pair and keystore


>cd %JAVA_HOME%\bin
>keytool -genkey -keystore mykeys.jks -alias gene
Enter keystore password: mykeystorepassword
What is your first and last name?
[Unknown]: Gene Telluride
What is the name of your organizational unit?
[Unknown]: Information Technologies
What is the name of your organization?
[Unknown]: The Daily Moon
What is the name of your City or Locality?
[Unknown]: New York
What is the name of your State or Province?
[Unknown]: NY
What is the two-letter country code for this unit?
[Unknown]: US
Is CN=Gene Telluride, OU=Information Technologies, O=The Daily Moon,
L=New York, ST=NY, C=U
S correct?

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 13 of 38
developerWorks® ibm.com/developerWorks

[no]: yes
Enter key password for <gene>
(RETURN if same as keystore password): mypassword

The command line tells the tool to generate a key pair and store it in the mykeys.jks
file. The key pair has an alias of gene, which lets us easily refer to it. Frances can
create her key and store it in the same file, mykeys.jks.

Now they're ready to start working on securing the service itself.

Enabling security
The first step in adding WS-Security to the service is to enable it on the server.
Apache Axis2, the Web services engine on which the team is running its services, is
built in a modular way, and the WS-Security module is called Rampart (see
Prerequisites for download information). Once you have downloaded Rampart, place
the rampart-1.0.mar file in the modules directory for your Axis installation. For
example, Gene's installation has the modules folder at
C:\SW\geronimo-1.0\config-store\32\war\WEB-INF\modules.

Next, Gene needs to make this module globally available, because in the "handler
chain" that works behind the scenes of Axis2, it needs to engage before the
message can be directed to a specific service. Restart Geronimo and log in to the
Axis2 administration page at http://localhost:8080/axis2/axis2-admin/login . (The
username is admin and the password is axis2.) Click Engage Module/For all
services and select rampart-1.0. Click Engage, as you can see in Figure 3.

Figure 3. Engaging the Rampart module

WS-Security
Page 14 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

You can also engage the Rampart module by adding the it to the axis2.xml file, as
you'll see when we look at securing the client.

Set security on the service


Now that the infrastructure is in place, Frances can start securing the actual service.
First, she shuts down Geronimo, because she wants to update the services.xml file
that's located in the CMSService.aar archive. (She has the option of updating and
re-uploading the service, but she's chosen to alter the archive directly.) The paper's
installation has the *.aar file at the location
C:\SW\geronimo-1.0\config-store\32\war\WEB-INF\services\CMSService.aar. She
updates the services.xml file to require a timestamp, as seen in Listing 14.

Listing 14. Adding a timestamp to the service


<service name="CMSService">
<description>
This is a sample Web Service for the newspaper's
Content Managment System.
</description>
<parameter name="ServiceClass"
locked="false">CMSService</parameter>
<parameter name="InflowSecurity">
<action>
<items>Timestamp</items>
</action>
</parameter>
<parameter name="OutflowSecurity">

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 15 of 38
developerWorks® ibm.com/developerWorks

<action>
<items>Timestamp</items>
</action>
</parameter>
<operation name="getNumberOfArticles">
<messageReceiver class=
"org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>

Axis2 enables Frances to specifically control messages flowing both into and out of
the service. In this case, she's told the Web services engine to require incoming
messages to include a Timestamp, and to include a Timestamp in the outgoing
messages returned to the client.

In a moment, we'll see the effect this change has on the messages passed between
server and client, but when Frances attempts to run a test, TCPMon shows that the
server returns an error rather than the expected information, as you can see in
Listing 15.

Listing 15. Missing security headers


<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsa:ReplyTo>
<wsa:Address>
http://www.w3.org/2005/08/addressing/anonymous
</wsa:Address>
</wsa:ReplyTo>
<wsa:MessageID>
urn:uuid:1CA9E94A9C7FE9D5B311507328796251
</wsa:MessageID>
<wsa:Action>
http://www.w3.org/2005/08/addressing/fault
</wsa:Action>
</soapenv:Header>
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Client</faultcode>
<faultstring>WSDoAllReceiver: Request does not
contain required Security header</faultstring>
<detail>
<Exception>org.apache.axis2.AxisFault: WSDoAllReceiver:
Request does not contain required Security
header at ...
</Exception>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>

The important thing here is that Frances now knows it's working; the engine won't
accept messages unless they conform to the security she's configured for the
service.

Now she can move on to the client.

Securing the client

WS-Security
Page 16 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

In many ways, the client is also a server of sorts, in that it also sends and receives
SOAP messages, so perhaps it should come as no surprise that Frances' first step
in securing the client is to add the rampart-1.0.mar to the client installation. To do
that, she first creates a new directory, <CLIENT_HOME>\axis-repo\modules, where
<CLIENT_HOME> is the directory in which the ClassifiedClient.class file is located.
She then adds the rampart-1.0.mar file to that directory. She also creates a second
directory, <CLIENT_HOME>\axis-repo\conf, in which she creates a new file,
axis2.xml. The file contains the code seen in Listing 16.

Listing 16. The original axis2.xml file


<axisconfig name="AxisJava2.0">
<!-- Engage the security module -->
<module ref="ramart"/>

<parameter name="OutflowSecurity">
<action>
<items>Timestamp</items>
</action>
</parameter>
<!-- <parameter name="InflowSecurity">
<action>
<items>Timestamp</items>
</action>
</parameter> -->
<!-- ================================================= -->
<!-- Parameters -->
<!-- ================================================= -->
<parameter name="hotdeployment"
locked="false">true</parameter>
<parameter name="hotupdate" locked="false">false</parameter>
<parameter name="enableMTOM" locked="false">true</parameter>
<!-- Uncomment this to enable REST support -->
<!-- <parameter name="enableREST"
locked="false">true</parameter>-->

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


<parameter name="password" locked="false">axis2</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>
<!-- ================================================= -->
<!-- Transport Ins -->
<!-- ================================================= -->
<transportReceiver name="http"
class="org.apache.axis2.transport.http.SimpleHTTPServer">
<parameter name="port" locked="false">6060</parameter>
<!--If you want to give your own host address for EPR
generation-->

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 17 of 38
developerWorks® ibm.com/developerWorks

<!--uncommet following paramter , and set as you required.-->


<!--<parameter name="hostname"
locked="false">http://myApp.com/ws</parameter>-->
</transportReceiver>
<transportReceiver name="tcp"
class="org.apache.axis2.transport.tcp.TCPServer">
<parameter name="port" locked="false">6061</parameter>
<!--If you want to give your own host address for EPR
generation-->
<!--uncommet following paramter , and set as you required.-->
<!--<parameter name="hostname"
locked="false">tcp://myApp.com/ws</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="jms"
class="org.apache.axis2.transport.jms.JMSSender"/>
<transportSender name="http"
class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">
<parameter name="PROTOCOL"
locked="false">HTTP/1.1</parameter>
<parameter name="Transfer-Encoding"
locked="false">chunked</parameter>
</transportSender>
<transportSender name="https"
class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">
<parameter name="PROTOCOL"
locked="false">HTTP/1.1</parameter>
<parameter name="Transfer-Encoding"
locked="false">chunked</parameter>
</transportSender>
<!-- ================================================= -->
<!-- Phases -->
<!-- ================================================= -->
<phaseOrder type="inflow">
<!-- System pre defined phases -->
<phase name="Transport">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.engine.RequestURIBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.engine.SOAPActionBasedDispatcher">
<order phase="Dispatch"/>
</handler>
</phase>
<phase name="Security"/>
<phase name="PreDispatch"/>
<phase name="Dispatch"
class="org.apache.axis2.engine.DispatchPhase">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.engine.AddressingBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher">
<order phase="Dispatch"/>

WS-Security
Page 18 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

</handler>
<handler name="InstanceDispatcher"
class="org.apache.axis2.engine.InstanceDispatcher">
<order phase="PostDispatch"/>
</handler>
</phase>
<!-- System pre defined phases -->
<!-- After Postdispatch phase module author or or
service author can add any phase he want -->
<phase name="OperationInPhase"/>
</phaseOrder>
<phaseOrder type="outflow">
<!-- user can add his own phases to this area -->
<phase name="OperationOutPhase"/>
<!--system predefined phase-->
<!--these phase will run irrespective of the service-->
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
</phaseOrder>
<phaseOrder type="INfaultflow">
<phase name="PreDispatch"/>
<phase name="Dispatch"
class="org.apache.axis2.engine.DispatchPhase">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.engine.RequestURIBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.engine.SOAPActionBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.engine.AddressingBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="InstanceDispatcher"
class="org.apache.axis2.engine.InstanceDispatcher">
<order phase="PostDispatch"/>
</handler>
</phase>
<!-- user can add his own phases to this area -->
<phase name="OperationInFaultPhase"/>
</phaseOrder>
<phaseOrder type="Outfaultflow">
<!-- user can add his own phases to this area -->
<phase name="OperationOutFaultPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
</phaseOrder>
</axisconfig>

Most of this code is boilerplate, borrowed from other Axis2 examples. In the bold
section at the top, however, Frances adds to tell the client to add a Timestamp to the
message that it sends to the server. She opts not to deal with the Timestamp
returned by the server, at least for the moment. Unlike the service, however, the
client won't automatically obey these directives. She's got to make changes to the
actual class.

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 19 of 38
developerWorks® ibm.com/developerWorks

Changes to the client class


In order for the client class to make the changes specified in the axis2.xml file, it has
to know about them. To that end, Frances adds the configuration into the process of
creating the ServiceClient, as seen in Listing 17.

Listing 17. Calling the new configuration from ClassifiedClient.java


...
public static void main(String[] args) {
try {
OMElement payload =
ClassifiedClient.getNumOfArticlesOMElement();
ConfigurationContext
configContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"axis-repo", null);
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
ServiceClient sender =
new ServiceClient(configContext, null);
sender.setOptions(options);
OMElement result = sender.sendReceive(payload);
String response = result.getText();
System.out.println("There are "+response+
" classifieds at the moment.");
} catch (Exception e) {
System.out.println(e.toString());
}
}
}

First, Frances creates a new ConfigurationContext, which enables the


ServiceClient to look for a new configuration. But in order to make it happen,
she'll need to change the way she calls the actual client class.

Pulling it all together


In order for the client to properly call the Rampart module, it needs to know where to
find the configuration file, and where to find any other repository items, such as the
*.mar file itself. To do that, Frances adds more detail to the script that sets her
classpath and runs the client class, as seen in Listing 18.

Listing 18. Calling the class


echo off
SET CLASSPATH=C:/SW/axis2/lib/XmlSchema-1.0.2.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/axiom-api-1.0.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/axiom-impl-1.0.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/axis2-kernel-1.0.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/commons-codec-1.3.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/commons-httpclient-3.0.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/commons-logging-1.0.4.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/
geronimo-spec-activation-1.0.2-rc4.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/
geronimo-spec-javamail-1.3.1-rc5.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/jaxen-1.1-beta-8.jar

WS-Security
Page 20 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/log4j-1.2.13.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/neethi-1.0.1.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/stax-api-1.0.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/wsdl4j-1.5.2.jar
SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/wstx-asl-2.9.3.jar
SET CLASSPATH=%CLASSPATH%;C:/sw/ClassifiedClient/lib/wss4j-1.5.0.jar
SET CLASSPATH=%CLASSPATH%;C:/sw/ClassifiedClient/lib/xmlsec-1.3.0.jar
SET CLASSPATH=%CLASSPATH%;C:/sw/ClassifiedClient/lib/
commons-discovery-0.2.jar
SET CLASSPATH=%CLASSPATH%;C:/sw/ClassifiedClient/lib/
bcprov-jdk13-132.jar
SET CLASSPATH=%CLASSPATH%;C:/sw/ClassifiedClient/lib/xalan.jar
SET CLASSPATH=%CLASSPATH%;.
java.exe -Daxis2.xml=axis-repo/conf/axis2.xml
-Daxis2.repo=axis-repo ClassifiedClient

Notice that Frances also adds several *.jar files from the WSS4J distribution (see
Prerequisites for download information).

Now she's ready to try the request once more.

The request
Running the request shows a normal SOAP message, with one exception, as seen
in Listing 19.

Listing 19. A Timestamped SOAP message


<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv=
"http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-
1.0.xsd" soapenv:mustUnderstand="1">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-
1.0.xsd" wsu:Id="Timestamp-29987161">
<wsu:Created>2006-06-19T16:22:28.578Z</wsu:Created>
<wsu:Expires>2006-06-19T16:27:28.578Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<cms:getNumberOfArticles xmlns:cms="http://daily-moon.com/cms">
<cms:category>classifieds</cms:category>
</cms:getNumberOfArticles>
</soapenv:Body>
</soapenv:Envelope>

Now, for the first time, Frances sees a Security header in her messages. In this
case, it's just a Timestamp, which shows when the message was created. The
mustUnderstand attribute means that if the server doesn't know what to do with this
Timestamp element, it must reject the message.

Timestamps are perhaps the simplest element of WS-Security. They provide a way
to limit the lifespan of messages, preventing malcontents from intercepting
messages, altering them at their leisure, and sending them on. In this case, the
Timestamp expires five seconds after the creation of the message, so if the
message is older than that, the message must be rejected. (Yes, a malcontent can
still alter the Timestamp values, but we'll deal with that when we get to signatures.)

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 21 of 38
developerWorks® ibm.com/developerWorks

The response
As specified in the service, the response also has a Timestamp, as seen in Listing
20.

Listing 20. The response


<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv=
"http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-
1.0.xsd" soapenv:mustUnderstand="1">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-
1.0.xsd" wsu:Id="Timestamp-22347273">
<wsu:Created>2006-06-19T16:22:29.281Z</wsu:Created>
<wsu:Expires>2006-06-19T16:27:29.281Z</wsu:Expires>
</wsu:Timestamp>
<wsse11:SignatureConfirmation xmlns:wsse11=
"http://docs.oasis-open.org/wss/2005/xx/oasis-2005xx-wss-wssecurity-
secext-1.1.xsd" xmlns:wsu="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-
1.0.xsd" wsu:Id="SigConf-5759024" />
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<resp:numberOfArcticles
xmlns:resp="http://daily-moon.com/cms/"
xmlns:tns="http://ws.apache.org/axis2"
>42</resp:numberOfArcticles>
</soapenv:Body>
</soapenv:Envelope>

The response includes the Timestamp, as specified, but also shows that the security
information has been processed and verified, even though Frances hasn't configured
the client to check either one of these facts.

Notice that in both cases, the actual messages were left intact.

Section 5. Signing messages


Now, at this point, Frances has added a Timestamp to both the outgoing and
incoming messages, but there's nothing to stop someone from simply changing its
value and retransmitting it. To solve that problem (and any other problems that arise
from information that may have been changed) Frances needs to look at signing her
messages.

How signing messages works

WS-Security
Page 22 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

As we've previously seen, signing a message involves creating a version of the data
that's been encrypted in a known way, so that decrypting it provides a value you can
compare to the original. For example, say that Frances wants to digitally sign the
Timestamp element in her messages so that the server can verify that they haven't
been tampered with or misappropriated in some way.

To do that, she's going to institute a process that will take several steps.

First, she will sign the message (or portion of the message). To do that, she'll use
the axis2.xml file to specify a user as the signer. Axis2 will take that information and
do two things with it. First, it will feed the user alias to a "callback class", which will
return the password for that user. Armed with that password, Axis2 will then retrieve
that user's private key from the keystore we created earlier.

Using the private key, Axis2 encrypts, or signs, the relevant part of the message and
adds the signature to the message. It then sends the message. When the service
receives the message, it does almost the same thing; it accesses the keystore to get
the public key for that user, and then it verifies the signature.

Note that if the service were going to send back content that has been signed, these
roles would be reversed for the return trip.

Let's look at getting this set up.

The callback class


The first step is to create the callback class. In a real situation, this class might
access an LDAP directory or use other methods for associating a username with a
password, but Frances is starting with a proof-of-concept, so she'll create a simple
callback class that returns arbitrary values, as you can see in Listing 21.

Listing 21. PWCallback.java, the callback class


import org.apache.ws.security.WSPasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
public class PWCallback implements CallbackHandler {
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof WSPasswordCallback) {
WSPasswordCallback pc=(WSPasswordCallback)callbacks[i];
if (pc.getIdentifer().equals("gene")) {
pc.setPassword("mypassword");
} else if (pc.getIdentifer().equals("frances")) {
pc.setPassword("francespassword");
} else {
throw new UnsupportedCallbackException(
callbacks[i], "Unknown user");
}
} else {
throw new UnsupportedCallbackException(callbacks[i],
"Unrecognized Callback");

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 23 of 38
developerWorks® ibm.com/developerWorks

}
}
}
}

What the class does in the handle() method isn't important; all that's important is
that it either sets the password on the WSPasswordCallback object or it throws an
exception.

The properties file


Next Frances has to find a way to tell Axis2 where to find the keystore, and what
class should actually perform all of this cryptographic wizardry. To do that, she
creates a properties file, security.properties, as seen in Listing 22:

Listing 22. The security.properties file


org.apache.ws.security.crypto.provider=org.apache.ws.security.compo
nents.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=mykeystorepa
ssword
org.apache.ws.security.crypto.merlin.file=mykeys.jks

After specifying the provider, the properties file defines the type of keystore -- in this
case, jks, the proprietary format that comes with Java -- the password for the
keystore, and the name of the actual keystore file, which for simplicity's sake she
puts in the same directory as the client class file.

The axis2.xml file


Now she needs to let the axis2.xml file what she's got in mind for outgoing
messages, as you can see in Listing 23.

Listing 23. The axis2.xml file, with signature


<axisconfig name="AxisJava2.0">
<!-- Engage the security module -->
<module ref="rampart"/>
<parameter name="OutflowSecurity">
<action>
<items>Signature</items>
<user>gene</user>
<passwordCallbackClass>PWCallback</passwordCallbackClass>
<signaturePropFile>security.properties</signaturePropFile>
<signatureKeyIdentifier>SKIKeyIdentifier</signatureK
eyIdentifier>
<signatureParts>{Element}{http://schemas.xmlsoap.org
/soap/envelope/}Body</signatureParts>
</action>
</parameter>
<!--
<parameter name="InflowSecurity">
<action>
<items>Timestamp</items>
</action>
</parameter>
-->
...

WS-Security
Page 24 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

In this case, instead of telling the client to add a Timestamp, she's telling it to add a
Signature. Seeing that, the client looks at the file specified in signaturePropFile
and uses the information found there -- along with the passwordCallbackClass
-- to get the password for the gene user. From there, it pulls gene's private key and
signs only the part of the message specified in the signatureParts element. In
this case, that means that the element represented by the Body (as opposed to just
that element's content), which is part of the
http://schemas.xmlsoap.org/soap/envelope/ namespace.

You can sign any part of the message. For example, people often sign the
Timestamp, if present.

The request
So what do all of these changes mean for the messages produced by the client?
You can see the resulting request in Listing 24.

Listing 24. The signed request


<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv=
"http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="..." soapenv:mustUnderstand="1">
<ds:Signature xmlns:ds="..." Id="Signature-8789796">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm=
"http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm=
"http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#id-17764792">
<ds:Transforms>
<ds:Transform Algorithm=
"http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm=
"http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue
>wg+9KsR6BVBiO/hakJJwMdtU7+I=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>hom9Enzu3yHBuaF...</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-19475750">
<wsse:SecurityTokenReference xmlns:wsu=".."
wsu:Id="STRId-31156635">
<wsse:KeyIdentifier EncodingType="http://docs.oasis
-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-
1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/o
asis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier"
>CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soapenv:Header>
<soapenv:Body xmlns:wsu="..." wsu:Id="id-17764792">
<cms:getNumberOfArticles xmlns:cms="http://daily-moon.com/cms">
<cms:category>classifieds</cms:category>
</cms:getNumberOfArticles>
</soapenv:Body>
</soapenv:Envelope>

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 25 of 38
developerWorks® ibm.com/developerWorks

I've snipped out namespace values to make this a bit more readable, but let's go
through it bit by bit. The Security element contains all of the security information,
of course, starting with the Signature. The signature starts with the information on
what was actually signed. Jumping forward just a little bit, the Reference element
includes a URI attribute, which refers back to the id attribute for the Body, which is,
remember, what Frances told the client to sign. So that tells the service what
information was actually signed.

Moving back up, the first step in signing content is to canonicalize it -- remove
extraneous text nodes, and so on -- but there are actually two ways to do that,
inclusive and exclusive, the difference being in how each method handles
namespace declarations. So the CanonicalizationMethod element specifies
which method the signature uses.

We then move to the SignatureMethod, which specifies, as the name suggests,


the method used to sign the relevant data.

The Reference element includes information on all of the steps that were taken to
arrive at the final content to sign, in order, so that the verification process can take
the same steps and (hopefully) arrive at the same SignatureValue.

The KeyInfo provides either the actual key used to sign the data or a reference to
the key.

Making changes to the service


Now the client is creating the signature, but the service doesn't know what to do with
it. Frances is about to change that.

In essence, the service needs to perform many of the same steps the client
performed; it needs to be able to find passwords and keys in the keystore, so
Frances starts by adding the mykeys.jks, PWCallback.class and security.properties
files to the CMSService.aar file. You don't have to use the same class and keystore
you used for the client, but in this case, she does it for the sake of convenience.

She also adds the bcprov-jdk13-132.jar, wss4j-1.5.0.jar, and xmlsec-1.3.0.jar to the


lib directory of the Axis2 application. (These files come from the WSS4J distribution.)

Frances then has to set the service definition (in services.xml) to recognize that
signed data is coming its way. She does that by making the changes shown in
Listing 25.

Listing 25. Telling the service to expect signed data


<service name="CMSService">
<description>
This is a sample Web Service for the newspaper's Content Managment System.
</description>
<parameter name="ServiceClass"
locked="false">CMSService</parameter>

WS-Security
Page 26 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

<parameter name="InflowSecurity">
<action>
<items>Signature</items>
<passwordCallbackClass>PWCallback</passwordCallbackClass>
<signaturePropFile>security.properties</signaturePropFile>
</action>
</parameter>
<parameter name="OutflowSecurity">
<action>
<items>Timestamp</items>
</action>
</parameter>
<operation name="getNumberOfArticles">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>

These changes are enough to let the service know what to expect and what to do
with the signed data.

The response
The response is a document that includes a Timestamp, as specified in the
OutFlowSecurity parameter, but also includes information about the verification
of the signature, as seen in Listing 26.

Listing 26. The response


<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv=
"http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="..." soapenv:mustUnderstand="1">
<wsu:Timestamp xmlns:wsu="..." wsu:Id="Timestamp-27995990">
<wsu:Created>2006-06-19T23:56:55.214Z</wsu:Created>
<wsu:Expires>2006-06-20T00:01:55.214Z</wsu:Expires>
</wsu:Timestamp>
<wsse11:SignatureConfirmation xmlns:wsse11="..."
xmlns:wsu="..." Value="hom9Enzu3yHBuaigFl26b6A+5hy..."
wsu:Id="SigConf-25877728" />
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<resp:numberOfArcticles xmlns:resp="http://daily-moon.com/cms/"
xmlns:tns="http://ws.apache.org/axis2">42</resp:numberOfArcticles>
</soapenv:Body>
</soapenv:Envelope>

Now let's look at adding encryption to the picture.

Section 6. Adding encryption


Frances is pleased with the process of verifying part of the message using

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 27 of 38
developerWorks® ibm.com/developerWorks

signatures, but there's still no way to obscure information so that competitors and
other miscreants can't read it. To take care of that, she'll have to add encryption to
the application.

Altering the service


This time, she starts with the service. She's already added all of the additional
classes the application needs, so all she needs to change is the services.xml file, as
you can see in Listing 27.

Listing 27. Adding encryption to the service


<service name="CMSService">
<description>
This is a sample Web Service for the newspaper's
Content Managment System.
</description>
<parameter name="ServiceClass"
locked="false">CMSService</parameter>
<parameter name="InflowSecurity">
<action>
<items>Timestamp Signature
Encrypt</items>
<passwordCallbackClass>PWCallback</passwordCallbackClass>
<signaturePropFile>security.properties</signaturePropFile>
</action>
</parameter>
<operation name="getNumberOfArticles">
<messageReceiver class=
"org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>

Here Frances has told the service that messages coming in will have had a
Timestamp added, and then they will have been signed, and then they will have
been encrypted -- in that order.

Now she just has to tell the client to do it.

Altering the client


Because she's already laid the groundwork, adding encryption to the client is also
straightforward, and involves just a simple change to the axis2.xml file, as you can
see in Listing 28.

Listing 28. Adding encryption to the client


<axisconfig name="AxisJava2.0">
<!-- Engage the security module -->
<module ref="rampart"/>

WS-Security
Page 28 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

<parameter name="OutflowSecurity">
<action>
<items>Timestamp Signature Encrypt</items>
<user>gene</user>
<passwordCallbackClass>PWCallback</passwordCallbackClass>
<signaturePropFile>security.properties</signaturePropFile>
<signatureKeyIdentifier
>SKIKeyIdentifier</signatureKeyIdentifier>
<encryptionKeyIdentifier
>SKIKeyIdentifier</encryptionKeyIdentifier>
<encryptionUser>frances</encryptionUser>
<signatureParts>{Element}{http://schemas.xmlsoap.org/soap/env
elope/}Body</signatureParts>
<optimizeParts>//xenc:EncryptedData/xenc:CipherData/xenc:Ciph
erValue</optimizeParts>
</action>
</parameter>
<!-- ================================================= -->
<!-- Parameters -->
<!-- ================================================= -->
<parameter name="hotdeployment"
locked="false">true</parameter>
...

Notice that Francis is specifying a different user for encryption than she used for the
digital signature. This isn't a requirement, but it is possible. Note also the addition of
the optimizeParts element, which specifies how Axis2 should represent the
encrypted data in the message.

Let's see how that all plays out.

The request
With everything in place, the message is becoming somewhat complex, as you can
see in Listing 29.

Listing 29. The signed, sealed, and encrypted request


<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv=
"http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<soapenv:Header>
<wsse:Security xmlns:wsse="..." soapenv:mustUnderstand="1">
<xenc:EncryptedKey Id="EncKeyId-229902">
<xenc:EncryptionMethod Algorithm=
"http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<ds:KeyInfo xmlns:ds="...">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="http://docs.oasis
-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-
1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/o
asis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier"
>Xeg55vRyK3ZhAEhEf+YT0z986L0=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>PpAOXj5P0W8ukm...</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#EncDataId-30957433" />
</xenc:ReferenceList>
</xenc:EncryptedKey>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 29 of 38
developerWorks® ibm.com/developerWorks

Id="Signature-17764792">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm=
"http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm=
"http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#id-30957433">
<ds:Transforms>
<ds:Transform Algorithm=
"http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm=
"http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>+ECkM6R4GQ7AQ=...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<SignatureValue>DIeP5AxVmfw...</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-16675983">
<wsse:SecurityTokenReference
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-
wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-21866740">
<wsse:KeyIdentifier
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-
wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-
wss-x509-token-profile-1.0#X509SubjectKeyIdentifier">
CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-
wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-13665843">
<wsu:Created>2006-06-20T00:46:58.263Z</wsu:Created>
<wsu:Expires>2006-06-20T00:51:58.263Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soapenv:Header>
<soapenv:Body xmlns:wsu="..." wsu:Id="id-30957433">
<xenc:EncryptedData Id="EncDataId-30957433" Type=
"http://www.w3.org/2001/04/xmlenc#Content">
<xenc:EncryptionMethod Algorithm=
"http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
<xenc:CipherData>
<xenc:CipherValue>DZ3vWPtabb5vBpZMlEYLPjFc8r2DMJ...
fSjXpBFa7gybNA==</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soapenv:Body>
</soapenv:Envelope>

Starting at the bottom, notice that the actual request is missing, or rather Axis2 has
replaced it with an EncryptedData element that includes information on how the
data was encrypted, as well as the actual encrypted data (in the CypherData and
CypherValue) elements.

The data was encrypted with a shared key, which means that the message has to
include that key so that it can by decrypted. The shared key has been encrypted with
the receiver's public key and embedded in the Header, in the EncryptedKey
element. This key also includes a ReferenceList, which includes a
DataReference that points back to the data this key was used to encrypt.

So to reverse direction, the receiver (in this case, the server) receives the message,
uses its own private key to decrypt the shared key, and then uses the shared key to
decrypt the body of the message.

WS-Security
Page 30 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

And after all that, what does the response look like?

The response
The response is pretty simple, actually, because Frances didn't set any
OutFlowSecurity on the server, as you can see in Listing 30.

Listing 30. The response


<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv=
"http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header />
<soapenv:Body>
<resp:numberOfArcticles xmlns:resp=
"http://daily-moon.com/cms/" xmlns:tns=
"http://ws.apache.org/axis2"
>42</resp:numberOfArcticles>
</soapenv:Body>
</soapenv:Envelope>

This is a perfectly valid SOAP response, except for one thing. You may remember
that Frances has set the client to expect, at the very least, a Timestamp in its own
InFlowSecurity. So after all that, the request will still fail unless both the server
and the client are producing and expecting the same security methods.

Section 7. Putting it all together


At this point Frances and Gene have a few disjointed examples, so they decide to
put everything together into a single implementation to show to Rudy.

The final service specification


Rudy wants the service to only accept requests from authorized individuals (or
entities), and he doesn't want the responses to be readable by competitors. To do
that, Gene and Frances set things up as follows:

1. The client will add a Timestamp, which it will need to sign with the private
key of an approved user. This takes care of the authorized access issue,
and prevents messages from being intercepted and replayed.

2. The server will add a Timestamp, but it will also encrypt the body of the
response so that eavesdroppers can't see the data that comes back.

Let's look at how it all comes together.

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 31 of 38
developerWorks® ibm.com/developerWorks

The service
On the service side, Gene sets up the services.xml file as seen in Listing 31.

Listing 31. The final services.xml file


<service name="CMSService">
<description>
This is a sample Web Service for the newspaper's
Content Managment System.
</description>
<parameter name="ServiceClass"
locked="false">CMSService</parameter>
<parameter name="InflowSecurity">
<action>
<items>Timestamp Signature</items>
<passwordCallbackClass>PWCallback</passwordCallbackClass>
<signaturePropFile>security.properties</signaturePropFile>
</action>
</parameter>
<parameter name="OutflowSecurity">
<action>
<items>Timestamp Signature Encrypt</items>
<user>gene</user>
<passwordCallbackClass>PWCallback</passwordCallbackClass>
<signaturePropFile>security.properties</signaturePropFile>
<signatureKeyIdentifier
>SKIKeyIdentifier</signatureKeyIdentifier>
<encryptionKeyIdentifier
>SKIKeyIdentifier</encryptionKeyIdentifier>
<encryptionUser>frances</encryptionUser>
<signatureParts>
{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body
</signatureParts>
<optimizeParts>
//xenc:EncryptedData/xenc:CipherValue/xenc:CipherData
</optimizeParts>
</action>
</parameter>
<operation name="getNumberOfArticles">
<messageReceiver class=
"org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>

The InflowSecurity is what the server expects -- a message that has had a
Timestamp added and then signed -- and OutflowSecurity is what it will send
back to the client -- a message that has been Timestamped and signed, with the
data encrypted.

The client
On the client side, Frances sets up the reverse, as you can see in Listing 32.

Listing 32. The final axis2.xml file

WS-Security
Page 32 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

<axisconfig name="AxisJava2.0">
<!-- Engage the security module -->
<module ref="rampart"/>
<parameter name="OutflowSecurity">
<action>
<items>Timestamp Signature</items>
<user>gene</user>
<passwordCallbackClass>PWCallback</
passwordCallbackClass>
<signaturePropFile>security.properties</signaturePropFile>
<signatureKeyIdentifier
>SKIKeyIdentifier</signatureKeyIdentifier>
<signatureParts>
{Element}{http://docs.oasis-open.org/wss/2004/01/oasis
-200401-wss-wssecurity-utility-1.0.xsd}Timestamp</signatureParts>
</action>
</parameter>
<parameter name="InflowSecurity">
<action>
<items>Timestamp Signature Encrypt</items>
<user>gene</user>
<passwordCallbackClass>PWCallback</passwordCallbackClass>
<signaturePropFile>security.properties</signaturePropFile>
<signatureKeyIdentifier
>SKIKeyIdentifier</signatureKeyIdentifier>
<encryptionKeyIdentifier
>SKIKeyIdentifier</encryptionKeyIdentifier>
<encryptionUser>frances</encryptionUser>
<signatureParts>
{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body
</signatureParts>
<optimizeParts>
//xenc:EncryptedData/xenc:CipherValue/xenc:CipherData
</optimizeParts>
</action>
</parameter>
<!-- ================================================= -->
<!-- Parameters -->
<!-- ================================================= -->
<parameter name="hotdeployment" locked="false">true</parameter>
...

Now the client will send messages that are timestamped and signed, and insist that
any responses must be timestamped, signed and encrypted.

Let's see what that means for the actual messages.

The request
Listing 33 shows the final request.

Listing 33. The final request


<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv=
"http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
soapenv:mustUnderstand="1">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
Id="Signature-5525185">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm=

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 33 of 38
developerWorks® ibm.com/developerWorks

"http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm=
"http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#Timestamp-1741620">
<ds:Transforms>
<ds:Transform Algorithm=
"http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm=
"http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>
TQSR9wUuJ7rJi582TsbNjiAUqZI=
</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>aRI5mvvvXZusAB/5cKCx/fOcW+CDjdk1F3Icl
lObVcEOWws9/mV4X2kWEX3hhwK7koX5jMPpl7AtLSbEh8UQGCa8yBua++yveprFl020To
VtePVOcWsBLM+9VHu9bJbhvaaps43RiUkym6xvVU/yL3eKTbhdhB/RQDI3kylXdas=
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-26644003">
<wsse:SecurityTokenReference xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
utility-1.0.xsd" wsu:Id="STRId-26174005">
<wsse:KeyIdentifier EncodingType="http://docs.oasi
s-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Bas
e64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier"
>CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/20
04/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="Timestamp-1741620">
<wsu:Created>2006-06-22T11:34:02.453Z</wsu:Created>
<wsu:Expires>2006-06-22T11:39:02.453Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<cms:getNumberOfArticles
xmlns:cms="http://daily-moon.com/cms">
<cms:category>classifieds</cms:category>
</cms:getNumberOfArticles>
</soapenv:Body>
</soapenv:Envelope>

The response
Listing 34 shows the final response.

Listing 34. The final response


<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv=
"http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004
/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
soapenv:mustUnderstand="1">
<xenc:EncryptedKey Id="EncKeyId-28585008">
<xenc:EncryptionMethod Algorithm=
"http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-soap-message-security-
1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2
004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKey
Identifier">Xeg55vRyK3ZhAEhEf+YT0z986L0=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>

WS-Security
Page 34 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>NSkylkASezzHSp37izSN3xnxf6v/zwN3C70uU2n
UTNk4a9xYxhNcgiVQuS2/Tm3/x3Jm1d9rj2V8x1uqlKmi89MFifN34SDxaDTMBFzhfRv4
CmQSITEFjY1ySVDvMb7WZszGDhVIGYkjcDkoK+SfWdxyuaUdNUbPgEihSnFVRXs=</xen
c:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#EncDataId-19400027" />
</xenc:ReferenceList>
</xenc:EncryptedKey>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
Id="Signature-17174249">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm=
"http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm=
"http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#id-19400027">
<ds:Transforms>
<ds:Transform Algorithm=
"http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm=
"http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>HfdufYEGpvPpfz2+HWKui4npV9s=</ds:Di
gestValue>
</ds:Reference>
<ds:Reference URI="#SigConf-17122634">
<ds:Transforms>
<ds:Transform Algorithm=
"http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm=
"http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>e88WWqudpvW69wN23fgZjQ9ZAio=</ds:Di
gestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>aZLon//vwkw2G2Jxcligxod/CgxMjwtlefZiho
yUz5FpgSY6RUoI5vuHX2unrWV+EVA2vWdtz/Iyq+RS7j4QtE2XTYovxdyiZPbKXNdFKHy
AkpDr0aDLG9rSjyFVcTrUKgAY06t10zi13Daq95nDMH+wAJCYUO0Vor/u0V9Iv7I=</ds
:SignatureValue>
<ds:KeyInfo Id="KeyId-22768665">
<wsse:SecurityTokenReference xmlns:wsu="http://docs.oa
sis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="STRId-18220809">
<wsse:KeyIdentifier EncodingType="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Bas
e64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier"
>CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/20
04/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="Timestamp-6400133">
<wsu:Created>2006-06-22T11:34:04.062Z</wsu:Created>
<wsu:Expires>2006-06-22T11:39:04.062Z</wsu:Expires>
</wsu:Timestamp>
<wsse11:SignatureConfirmation xmlns:wsse11="http://docs.oasi
s-open.org/wss/2005/xx/oasis-2005xx-wss-wssecurity-secext-1.1.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-
wssecurity-utility-1.0.xsd" Value="aRI5mvvvXZusAB/5cKCx/fOcW+CDjdk1F3
IcllObVcEOWws9/mV4X2kWEX3hhwK7koX5jMPpl7AtLSbEh8UQGCa8yBua++yveprFl02
0ToVtePVOcWsBLM+9VHu9bJbhvaaps43RiUkym6xvVU/yL3eKTbhdhB/RQDI3kylXda
s=" wsu:Id="SigConf-17122634" />
</wsse:Security>
</soapenv:Header>
<soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/o
asis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-19400027">
<xenc:EncryptedData Id="EncDataId-19400027" Type=
"http://www.w3.org/2001/04/xmlenc#Content">
<xenc:EncryptionMethod Algorithm=

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 35 of 38
developerWorks® ibm.com/developerWorks

"http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
<xenc:CipherData>
<xenc:CipherValue>f6uWHGsYmGwHuno2j4H7a4qCMhPLTlCIg40p
KLciESBzeCT8rvyl+qHXsFkZJq2m4uj9TEFtRX6efQ5MHBEJozMgI03LSVanh6MmHgt5o
ilIJClWcQifEx0Azeo3KWnQKSc9lg0ywhKJH+JVBsPSP7E19jZAsR77wUEBBIprxs5W59
7C/mJh38iXSncwWccE7OCckf1x34FCfKHSqn46MCohZWiPZRjSmAI5dGFMKwttzpmsmXr
LHLVrsjm4w9onis+Xr5gbi3Gcx6P0F2ZJGLBb9bkGh/IvjYutgzRD7zhyRZxUmM/oZTVs
JJ7dA9YOED5l1C64f4yuqR6TtuVw3gIiuspxWafKwlJuuD0/9m6Ri4AvQuOVEioz45MM
5FBCQU+0LFceSlEFFKhN9yLUI9hgLsCYRzc8eedPAhZDjJEDHec5M9LZ0C07sKu7Cvnr
jiino53xZmk5uQHs4JlNoA==</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soapenv:Body>
</soapenv:Envelope>

Section 8. Summary
In order for Web services to be truly useful in the enterprise environment, it needs to
have the appropriate security capabilities. By combining with technologies such as
XML Signature and XML Encryption and providing a standard way of presenting that
information, WS-Security makes it possible to protect both incoming and outgoing
SOAP messages from several different security threats.

By requiring digital signatures, you can limit access to authorized individuals or


organizations, as well as verifying that information has not been altered in transit. By
including encryption, you can prevent data from being seen (or at least understood)
by unintended recipients. And by adding a Timestamp (and signing it) you can
prevent messages from being captured and replayed.

In this tutorial, the staff at the Daily Moon secured the Web services they created in
earlier parts of this series. Next, in Part 5, they will look at applying security policies
to the service.

WS-Security
Page 36 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®

Resources
Learn
• Read the WS-Security specification.
• Read the Username Token Profile (PDF).
• Read the at X.509 Token Profile (PDF).
• Read the XML Signature specification.
• Read the XML Encryption specification at http://www.w3.org/Encryption/2001/.
• To get a good grounding in XML, read the Introduction to XML tutorial
(developerWorks, August 2002).
• For a better understanding of dealing with XML as an object, read
Understanding DOM (developerWorks, July 2003).
• You can find a wealth of information on the developerWorks SOA and Web
Services zone.
• See an example of Axis2 at work by reading the Online banking with Apache
Geronimo and Axis2 tutorial series.
• To learn more about programming in Java, check out the developerWorks Java
zone.
• Learn all about XML at the developerWorks XML zone.
Get products and technologies
• Download Apache Geronimo. For more information on installing Geronimo, see
Part 1 of this series.
• Download Apache Axis2 version 1.0 or higher.
• Download the Apache Axis2 Rampart module.
• Download Apache WSS4J.
• Download Java 2 Standard Edition version 1.4.2 or higher.
• Download TCPMon.
• Download GnuPG.

About the author


Nicholas Chase
Nicholas Chase has been involved in Web-site development for companies such as
Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers.
Nick has been a high school physics teacher, a low-level radioactive waste facility
manager, an online science fiction magazine editor, a multimedia engineer, an Oracle

WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 37 of 38
developerWorks® ibm.com/developerWorks

instructor, and the chief technology officer of an interactive communications


company. He is the author of several books, including XML Primer Plus .

WS-Security
Page 38 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.

You might also like