Professional Documents
Culture Documents
4: WS-Security
Skill Level: Intermediate
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.
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.
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.
• 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.
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.
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.
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.
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.
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 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 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 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).
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.
WS-Security
Page 6 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.
ibm.com/developerWorks developerWorks®
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.
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.
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:
WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 9 of 38
developerWorks® ibm.com/developerWorks
</cms:getNumberOfArticles>
</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.
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.
To make things simple, he uses the free GnuPG program, executing the command
shown in Listing 8.
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.
Certainly nobody would guess the original text from that! Encouraged, Gene moves
on to look at the issue of digital signatures.
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.
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.
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.
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.
To create a new key and generate a keystore, he executes the following commands,
as seen in Listing 13.
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.
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.
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.
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.
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.
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.
<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>-->
WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 17 of 38
developerWorks® ibm.com/developerWorks
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
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).
The request
Running the request shows a normal SOAP message, with one exception, as seen
in Listing 19.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
The request
With everything in place, the message is becoming somewhat complex, as you can
see in Listing 29.
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.
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.
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.
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.
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.
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.
The request
Listing 33 shows the final request.
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.
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.
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.
WS-Security
© Copyright IBM Corporation 1994, 2006. All rights reserved. Page 37 of 38
developerWorks® ibm.com/developerWorks
WS-Security
Page 38 of 38 © Copyright IBM Corporation 1994, 2006. All rights reserved.