This is G o o g l e's text-only cache of http://procmgmt.raba.com/techInsertion/deploy/software/webServices/deploy/doc/whitepapers/wsSecurity/public/wss-wp.html as retrieved on Jul 25, 2005 21:40:59 GMT.
G o o g l e's cache is the snapshot that we took of the page as we crawled the web.
The page may have changed since that time. Click here for the current page without highlighting.
Click here for the full cached page with images included.
To link to or bookmark this page, use the following url: http://www.google.com/search?q=cache:16pSU6hP0P4J:procmgmt.raba.com/techInsertion/deploy/software/webServices/deploy/doc/whitepapers/wsSecurity/public/wss-wp.html+wss4j+jwsdp+comparison&hl=en&lr=&strip=1


Google is neither affiliated with the authors of this page nor responsible for its content.
These search terms have been highlighted: wss4j jwsdp comparison 

Comparison of WS-Security Toolkits

Comparison of WS-Security Toolkits

January 14, 2005
By Keith Fisher


Table of Contents

Introduction
Security Overview
WS-Security Overview
   Security Tokens
   Signatures
   Encryption
Sample WS-Security Scenarios
Apache WSS4J
   
Implementing the Sample Scenarios
   Running the Sample Application
Sun JWSDP 1.5
   Implementing the Sample Scenarios
   Running the Sample Application
webMethods Glue 5.0.2
   Implementing the Sample Scenarios
   Running the Sample Application
Interoperability of WS-Security Toolkits
Summary
Further Reading

Introduction

Web services enable software applications to communciate and conduct transactions by adopting XML as a data exchange format and industry standard delivery protocols. Security is a requirement for adopting Web services in critical applications. The integrity and confidentiality of SOAP messages exchanged between Web services providers and clients must be guaranteed. In addition, the identities of the participating parties must be assured. In April 2002, IBM, Microsoft, and VeriSign co-authored a draft of the WS-Security specification, which addresses these security concerns. The Organization for the Advancement of Structured Information Standards (OASIS) ratified WS-Security as a standard under the name OASIS Web Services Security (WSS) in April 2004.

The WS-Security specification has three main goals:

Transport-level mechanisms like HTTP authentication and HTTPS (HTTP over Secure Sockets Layer, or SSL) provide these capabilities, but transport level security isn't flexible enough for some applications. The shortcomings of transport level security using HTTP and HTTPS are exhibited in these scenarios:

The WS-Security standard addresses these limitations by providing flexible security mechanisms that can be applied to subsections of individual SOAP messages. WS-Security makes use of the XML Signature specification (to make messages tamper-proof), the XML Encryption specification (to keep messages secret), and provides for attaching security tokens (like user names and passwords) to a message.

This white paper presents an overview of message security, the WS-Security specification, and describes use cases that utilize WS-Security features. The paper includes code samples for the scenarios from three toolkits that implement the WS-Security specification:

Security Overview

The meaning of the phrase "message security" includes these three requirements: authentication, integrity, and confidentiality.

Authentication is used to ensure the identity of the message senders. The combination of a user name and a secret password is commonly used to assert an identity. A more complex example uses an X.509 certificate issued from a trusted Certificate Authority. The certificate contains identity credentials and has a private/public key pair associated with it. A sender's proof of identity includes the certificate itself and a separate piece of information that is digitally signed using the certificate's private key. The receiver authenticates the sender as the owner of the certificate by using the certificate's public key to validate the signed information. This confirms the sender's identity.

Digital signatures can be used to ensure a message's integrity, that its content has not been altered or corrupted during its transmission over the network. A common practice is to use the private key of the sender's X.509 certificate to digitally sign the SOAP Body of a Web services request. Elements in the SOAP Header of a request also can be signed to ensure the integrity of information that is outside the scope of the actual business operation (for example, security tokens). A Web services response can also be digitally signed to ensure data integrity.

Encryption is used to ensure message confidentiality. Encryption ensures that anyone accessing the data in transit, in memory, or after it has been persisted, needs the appropriate algorithms and security keys to decrypt the data and be able to access the actual information.

WS-Security Overview

The WS-Security specification provides mechanisms to address the three security requirements outlined above. With WS-Security, you can selectively employ one or more of the mechanisms to implement your specific security requirements.

Security Tokens

The WS-Security specification defines a set of XML elements called Security Tokens that can be attached to the SOAP message to satisfy the authentication requirement. Security tokens can be used by themselves, or associated with signature or encryption elements. The specification defines two types of security tokens:

This is an example of a UsernameToken with a hashed password generated by the webMethods Glue toolkit:

<soap:Header>
<wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:UsernameToken xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext"
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
wsu:Id="electric-id-91E90B44-1C8F-0607-BF4F-8B3E3D242EBA">
<wsse:Username>Ron</wsse:Username>
<wsse:Password Type="wsse:PasswordDigest">1OjLUItM4JKW4D4feXBKuSccBOg=</wsse:Password>
<wsse:Nonce>0pHV+YqqsotZvuwTzVUoUw==</wsse:Nonce>
<wsu:Created>2004-11-11T15:47:10.814Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>

A BinarySecurityToken of type X509v3 encodes an X.509 public key certificate as a base64-encoded XML Text element. Certificates are associated most often with digital signatures.

<soap:Header>
<wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:BinarySecurityToken ValueType="wsse:X509v3" EncodingType="wsse:Base64Binary"
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
Id="electric-id-7E361F23-2BD1-BE93-9349-911ADAE40DEB">
MIICAjCCAWsCBD2jp0...
</wsse:BinarySecurityToken>
</wsse:Security>
</soap:Header>

Since security tokens are attached directly to a message, they can be used with JMS, SMTP, or any other transport that supports SOAP. That isn't possible with a transport-level scheme like HTTP Basic or Digest authentication.

Signatures

A digital signature enables the recipient of a message to determine if it was altered in transit. The WS-Security specification builds on the XML Signature specification to implement signatures. Understanding the low-level details of how signatures work is beyond the scope of this white paper, but the steps include:

Canonicalization
Generating a canonical form of an XML document that can be compared, byte-by-byte, to the canonical forms of other documents. Canonical forms of any two logically equivalent XML documents are always byte-by-byte identical.
Message Digest
A message digest algorithm takes a message and converts it into a small, fixed-length number. For example, a one-way hash function can compute a value like this for the body of a SOAP message:
   QZf8nqRVViEkYS3V20p2FoVht1M=
Any change in the message changes the resultant message digest. Multiple digests can be attached to a SOAP message, each referencing different, or even overlapping parts of the message.
Encryption
A message digest protected by encryption is called a "digital signature." The recipient of the message can decrypt the signature if the sender includes an X.509 certificate that holds the public key corresponding to the private key used to encrypt the digest value.
Encryption

The WS-Security standard leverages the XML Encryption standard to allow encryption of any portion of the SOAP message. The encryption of data is a two-phase process using both symmetric and asymmetric algorithms that involves these steps:

Sample WS-Security Scenarios

The WS-Security specification supports a broad range of security mechanisms for both a Web services provider and its clients. As described above, these include security tokens, digital signatures, and encryption. It's possible to combine these security actions in many ways, for example to encrypt parts of a message and sign other parts. To exercise each toolkit's implementation of the specification, we developed a sample Web services application that can be configured with multiple client and server-side security features. We selected three scenarios that represent likely customer use cases to secure Web services. Table 1 lists each of the scenarios and provides a brief description of the security configuration used for each.

Table 1  Sample WS-Security Scenarios
Scenario
Description
Scenario A
  • Client adds a UsernameToken.
  • Client encrypts the UsernameToken before sending the request.
  • Server decrypts the UsernameToken.
  • Server authenticates the user name and password against database.
  • Server sends the response.
Scenario B
  • Client signs and then encrypts and sends the request body.
  • Server decrypts and verifies the signature.
  • Server signs and then encrypts and sends the response.
Scenario C
  • Client signs and then encrypts a single XML element in the request body.
  • Client sends the request.
  • Server decrypts the request body element and verifies the signature.
  • Server signs and then encrypts and sends the response.

We selected a Web service from the WS-I Basic Profile 1.0 as an example application. WS-I, the Web Services Interoperability Organization, is focused on promoting the interoperability of Web services applications across different computing environments and programming languages. WS-I Basic Profile 1.0 is a collection of requirements to support interoperability and focuses on on the core foundational technologies upon which Web services are based: HTTP, SOAP, WSDL, UDDI, XML, and XML Schema. The profile includes usage scenarios, sample applications, and test tools that can be used by developers to test Web services for profile conformance.

WS-I chartered a working group to create a sample application to demonstrate to Web services developers how to use WS-I Basic Profile 1.0 to develop interoperable Web services. The sample application depicts a Supply Chain Management application for a fictitious consumer electronics retailer. The first system in the Supply Chain Management sample is the Retailer System. The Retailer Service has two operations: getCatalog() and submitOrder(). The getCatalog() operation returns a list of all the products that the retailer sells. The second operation, submitOrder(), takes as input information about the customer and the product(s) being ordered, and returns status information as to which of the ordered product(s) have been shipped. We applied the three WS-Security scenarios to the submitOrder() operation. The WSDL and XML Schema files for the Retailer Service are included with the code samples.

Apache WSS4J

Apache WSS4J provides an open source implementation of WS-Security using open source libraries like Apache XML Security. WSS4J is a subproject of the Apache Web Service Functionality Extensions (WS-FX) project, which includes implementations of the WS-Addressing and WS-ReliableMessaging specifications. WSS4J provides resources for building interoperable, trusted Web services using the WS-Security standard. The libraries can be deployed to provide protocol support for both client and server applications. In a typical situation, a Web service relies on these libraries to add secure messaging to whatever business logic the Web service supports. The libraries support both Apache Axis handlers and JAX-RPC based handlers for signing and verification of SOAP messages using WS-Security.

WSS4J leverages Apache Axis as its SOAP engine. The design of the Axis architecture is based on configurable "chains" of message "handlers" which implement discrete functions in a very flexible manner. An Axis handler is a reusable class responsible for processing a SOAP message in some custom way. The Axis engine invokes a series of handlers for both outgoing request messages and incoming response messages. The org.apache.ws.security package in WSS4J provides classes and interfaces that implement Axis handlers and process SOAP requests according to the WS-Security specifications. The WSS4J Axis handlers WSDoAllSender and WSDoAllReceiver control the creation and consumption of secure SOAP requests.

The WSS4J implementation benefits from leveraging the Axis handler architecture. It allows a clean separation of a Web service's business logic from the security processing logic. The handlers allow a developer to add security features to a service with minimal impact on existing code and configurations. The clean separation between the business logic and its service-specific handlers means that security mechanisms can be added and removed as needed. The Axis Web Service Deployment Descriptor (*.wsdd) files can declaratively specify all the properties needed to control the security processing for both the Web services provider and client.

Implementing the Sample Scenarios

The following snippet from the WSS4J documentation shows the syntax of a WSS4J Axis handler for a client of a Web service called Ping1:

 <!-- define the service, use the WSDoAllSender security handler in request flow -->
<service name="Ping1">
<requestFlow>
<handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
<parameter name="action" value="UsernameToken"/>
<parameter name="user" value="werner"/>
<parameter name="passwordType" value="PasswordText" />
<parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback1"/>
</handler>
</requestFlow>
</service>

Axis parses the deployment descriptor and provides the parameters and their values to the designated handler. Each service can have its own request and response flow definition, which provides a flexible definition of the security parameters.

The example above inserts a simple UsernameToken security structure into a SOAP request. The token includes a user name and the matching password. Because both fields are sent in clear text, it's meant as an example of the syntax of the WSS4J Axis handler and not as a best practice.

The parameters and their meanings are:

The WSS4J security handler interprets the parameter values and controls the WSS4J modules to generate the following SOAP request:

 <?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
soapenv:mustUnderstand="true">
<wsse:UsernameToken>
<wsse:Username>werner</wsse:Username>
<wsse:Password Type="wsse:PasswordText">security</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<Ping xmlns="http://xmlsoap.org/Ping">
<text>Scenario 1 text</text>
<ticket xmlns:ns1="http://xmlsoap.org/Ping"
xsi:type="ns1:ticketType">scenario1</ticket>
</Ping>
</soapenv:Body>
</soapenv:Envelope>

The deployment descriptor contains the user name that the handler inserts into the UsernameToken but not the password. In general, it is not a good practice to store sensitive information like a password in clear text. The WSS4J Axis handler uses a password callback technique similar to the Java Authentication and Authorization Service (JAAS) mechanism to get the password. The parameter passwordCallbackClass contains the classname of the callback class. The WSS4J Axis handler gets this class, instantiates it, and calls the handle() method when it needs a password.

Application sets parameters in the UsernameToken

If parameters and their values can't be determined during deployment, the application can set them during runtime. A Web service client that uses stubs generated by Axis' WSDL2Java tool can use the Axis _setProperty() method to support this feature. The following code snippet shows how to set parameters and their values:

    ...
PingServiceLocator service = new PingServiceLocator();
...
PingPort port = (PingPort) service.getPing1();
((org.apache.axis.client.Stub)port)._setProperty(UsernameToken.PASSWORD_TYPE, WSConstants.PASSWORD_TEXT);
((org.apache.axis.client.Stub)port)._setProperty(WSDoAllConstants.USER, "werner");
...

Deployment of the WSS4J Axis WSDoAllReceiver handler

On the server-side, the Web service provider defines a deployment descriptor for the WSDoAllReceiver handler. The WSS4J deployment descriptor for the UsernameToken example described above looks like this:

  <requestFlow>
<handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
<parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback"/>
<parameter name="action" value="UsernameToken"/>
</handler>
</requestFlow>

Scenario A - Combine UsernameToken and Encryption

The Scenario A use case specifies that the client adds an encrypted UsernameToken to the Web service request. The WSS4J Axis handler to combine these two security actions on the client-side looks like this:

  <requestFlow>
<handler name="DoScenarioASender" type="java:org.apache.ws.axis.security.WSDoAllSender" >
<parameter name="action" value="UsernameToken Encrypt"/>
<parameter name="user" value="Chris"/>
<parameter name="passwordCallbackClass" value="ws.security.wss4j.PWCallback"/>
<parameter name="passwordType" value="PasswordText" />
<parameter name="addUTElements" value="Nonce Created" />
<parameter name="encryptionPropFile" value="wsstest.properties"/>
<parameter name="encryptionKeyIdentifier" value="SKIKeyIdentifier"/>
<!-- Use the Server's cert/public key to encrypt the request -->
<parameter name="encryptionUser" value="c82f74d031dabf9d7546f40ad07c32c0_1e149434-9d3a-4adc-9284-4cfdc595012f"/>
<parameter name="encryptionParts"
value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}UsernameToken"/>
</handler>
</requestFlow>

This descriptor contains additional parameters to control the UsernameToken element and its encryption. The new parameters and their meaning are:

The matching deployment descriptor for the Web service on the server-side is:

  <requestFlow>
<handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
<parameter name="passwordCallbackClass" value="ws.security.wss4j.PWCallback"/>
<parameter name="action" value="UsernameToken Encrypt"/>
<parameter name="decryptionPropFile" value="crypto.properties" />
</handler>
</requestFlow>

The only new parameter in this descriptor is the decryptionPropFile. This parameter defines the crypto property file on the server-side. The value of the action parameter matches the value on the client-side. The WSS4J Axis handler checks if the SOAP request contains the required security data.

Scenario B - Combine Signature and Encryption

The Scenario B use case specifies that the client signs and encrypts the SOAP Body of the request. The server decrypts the message and verifies the signature, and then signs and encrypts the response. A WSS4J Axis deployment descriptor for this scenario is:

 <requestFlow>
<handler name="DoScenarioBSender" type="java:org.apache.ws.axis.security.WSDoAllSender" >
<parameter name="action" value="Signature Encrypt"/>
<parameter name="passwordCallbackClass" value="ws.security.wss4j.PWCallback"/>
<!-- Use the Client's cert/private key to sign the request -->
<parameter name="user" value="1fb7623be7b2f4831ffc3f3741fa09dd_1e149434-9d3a-4adc-9284-4cfdc595012f"/>
<parameter name="signatureKeyIdentifier" value="DirectReference" />
<parameter name="signaturePropFile" value="wsstest.properties" />
<!-- Use the Server's cert/public key to encrypt the request -->
<parameter name="encryptionUser" value="c82f74d031dabf9d7546f40ad07c32c0_1e149434-9d3a-4adc-9284-4cfdc595012f"/>
<parameter name="encryptionKeyIdentifier" value="SKIKeyIdentifier" />
</handler>
</requestFlow>

This deployment descriptor signs and encrypts the SOAP Body element of the message. The interesting parameters and their meanings are:

The matching <requestFlow> specification in the Web service provider's deployment descriptor is fairly simple:

 <requestFlow>
<handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
<parameter name="passwordCallbackClass" value="ws.security.wss4j.PWCallback"/>
<parameter name="action" value="Signature Encrypt"/>
<parameter name="signaturePropFile" value="crypto.properties" />
</handler>
</requestFlow>

The Web service provider's <responseFlow> element is nearly identical to the client's <requestFlow>. The changes are to the user and encryptionUser parameters. On the server-side, the server's private key is used to sign the response and the client's public key is used to encrypt the randomly generated symmetric key.

Scenario C - Signing and Encrypting a Single XML Element

The Scenario C use case specifies that the client signs and then encrypts a single XML element in the SOAP request body. The server decrypts the element and verifies the signature, and then signs and encrypts an element in the response. The WSS4J deployment parameters signatureParts and encryptionParts control which SOAP elements to sign or encrypt.

 <requestFlow>
<handler name="DoScenarioCSender" type="java:org.apache.ws.axis.security.WSDoAllSender" >
<parameter name="action" value="Signature Encrypt"/>
<parameter name="passwordCallbackClass" value="ws.security.wss4j.PWCallback"/>
<!-- Use the Client's cert/private key to sign the request -->
<parameter name="user" value="1fb7623be7b2f4831ffc3f3741fa09dd_1e149434-9d3a-4adc-9284-4cfdc595012f"/>
<parameter name="signatureKeyIdentifier" value="DirectReference" />
<parameter name="signaturePropFile" value="wsstest.properties" />
<parameter
name="signatureParts"
value="{Element}{http://www.ws-i.org/SampleApplications/SupplyChainManagement/2002-08/RetailOrder.xsd}custnbr"/>
<!-- Use the Server's cert/public key to encrypt the request -->
<parameter name="encryptionUser" value="c82f74d031dabf9d7546f40ad07c32c0_1e149434-9d3a-4adc-9284-4cfdc595012f"/>
<parameter name="encryptionKeyIdentifier" value="SKIKeyIdentifier"/>
<parameter
name="encryptionParts"
value="{Element}{http://www.ws-i.org/SampleApplications/SupplyChainManagement/2002-08/RetailOrder.xsd}custnbr"/>
</handler>
</requestFlow>

The values of the signatureParts and encryptionParts parameters in this example specify to sign and encrypt the <custnbr> element, contained in the namespace http://www.ws-i.org/SampleApplications/SupplyChainManagement/2002-08/RetailOrder.xsd.

WSS4J signs or encrypts all declared parts using the same keys, that is, the signature or encryption data structures directly reference the specified parts as described in the WS-Security specifications. The receiver automatically detects these references and verifies and decrypts the data parts. No special settings in the <requestFlow> element in the Web service provider's deployment descriptor are necessary. The provider's <responseFlow> element defines properties to sign and encrypt an XML element in the response.

Running the Sample Application

A binary download of WSS4J is not yet available. The WSS4J Source Repository web page has instructions on how to check out the source code from the project's CVS repository. The ant target jar in the build.xml file compiles the code and builds the wss4j.jar JAR file. The jar target depends on the compile and test targets. I encountered errors when the test target ran, however, and I commented out the dependency in the compile target. The JavaDoc for the org.apache.ws.axis.security package provides a valuable introduction to the WSS4J Axis handlers and the syntax of the deployment descriptors.

The sample code for the WS-Security scenarios is in the wss4jUtil directory. Here is an overview of the contents of the directory:

build/client
Java object classes built by the ant target compile-client.
build/server
Java object classes built by the ant target compile-server.
build/war
Web application built by the ant target make-war.
client/ws/security/wss4j
Java source code for the scenario clients.
client/org/apache/axis/wsi/scm
Java client stubs generated by the ant target gen-client, which runs the Axis WSDL2java utility.
config/keystores
Contains the keystore file from the <wss4j.home>/wss4j/interop directory of the WSS4J repository. Used by the scenario clients and Web service.
config/logging
log4j.properties file used by the scenario clients.
config/wsdd
Axis deployment descriptor files for the scenario clients and Web service.
server/ws/security/wss4j
Java source code for the implementation of the Web service.
server/org/apache/axis/wsi/scm
Java server artifacts generated by the ant target gen-server, which runs the Axis WSDL2java utility.
webapps/wss4j
JSP, HTML page, and Web application file from the Apache Axis distribution which are included in the sample wss4j Web application.
wsdl
WSDL and XML Schema files for the Retailer Web service from the WS-I.
Running the Scenarios

The WSS4J Web application WAR file must be hosted in a Web container. To test the sample application, we downloaded Jakarta Tomcat version 5.0.28 from the Jakarta downloads page.

Several of the properties in the wss4jUtil/build.properties file need to be configured specifically for your system. Find the following properties and set the correct values for your system:

# place where WSS4J is installed
wss4j.home=<directory_location_of_your_WSS4J_installation>

# the host and port for the server endpoint
endpoint.host=localhost
endpoint.port=8060

The Axis TCP Monitor (tcpmon) utility is a helpful tool for debugging Web services applications. Use tcpmon to capture the exchange of SOAP messages between the scenario clients and the Web service. To run tcpmon, first add the axis.jar file to your Java CLASSPATH environment variable. Then type the following command to run tcpmon:
   % java org.apache.axis.utils.tcpmon 8060 localhost 8080

tcpmon monitors the local port (specified as the first argument) for incoming connections and forwards the intercepted traffic to the designated target host and port. Each time a SOAP connection is made to the local port, the tcpmon GUI displays the request in the "Request" panel, and the response from the server in the "Response" panel.

Running the Scenarios

Type the following commands at a command prompt to build the code for the WSS4J samples:
   % ant compile-client
   % ant compile-server
   % ant make-war

To see a list of useful ant targets, type the command:
   % ant help

After running the make-war target, deploy the server-side WAR file to the Tomcat container. If the CATALINA_HOME environment variable is set to the full pathname of the install directory, type the following command from the wss4jUtil directory:
   % cp build/war/wss4j.war $CATALINA_HOME/webapps

Tomcat must be restarted to deploy a new Web application copied into the webapps directory. To run Tomcat in the foreground so that the console output is visible, type the following command from your Tomcat installation directory:
   % bin/catalina.sh run

Running the Retailer Web Service without WS-Security Constraints

Type the following command at a command prompt:
   % ant run-example

If the client runs successfully, the output looks like the following:
   runclient:
      [echo] Running the ws.security.wss4j.RetailerClient program....
      [java] main:service URL=http://localhost:8060/wss4j/services/RetailerPort
      [java] Product Number/Comment: 605006/insufficient stock, 605002/in stock from WarehouseA, 605003/insufficient stock

Running Scenario A

Type the following command at a command prompt:
   % ant run-sca

If the client runs successfully, the output looks like the following:
   runclient:
      [echo] Running the ws.security.wss4j.ScenarioAClient program....
      [java] main:service URL=http://localhost:8060/wss4j/services/ScenarioA
      [java] 14:57:42,715 INFO - Using Crypto Engine [org.apache.ws.security.components.crypto.Merlin]
      [java] PWCallback: getIdentifier() = Chris
      [java] PWCallback: getUsage() = 2
      [java] Product Number/Comment: 605006/insufficient stock, 605002/in stock from WarehouseA, 605003/insufficient stock

In the tcpmon Request panel, the user name and password are encrypted in the SOAP header in the <wsse:Security> element of the client request. The server response is entirely in the clear.

Running Scenario B

Type the following command at a command prompt:
   % ant run-scb

If the client runs successfully, the output looks like the following:
   runclient:
      [echo] Running the ws.security.wss4j.ScenarioBClient program....
      [java] main:service URL=http://localhost:8060/wss4j/services/ScenarioB
      [java] 15:26:27,493 INFO - Using Crypto Engine [org.apache.ws.security.components.crypto.Merlin]
      [java] PWCallback: getIdentifier() = 1fb7623be7b2f4831ffc3f3741fa09dd_1e149434-9d3a-4adc-9284-4cfdc595012f
      [java] PWCallback: getUsage() = 3
      [java] 15:26:31,181 INFO - Using Crypto Engine [org.apache.ws.security.components.crypto.Merlin]
      [java] PWCallback: getIdentifier() = 1fb7623be7b2f4831ffc3f3741fa09dd_1e149434-9d3a-4adc-9284-4cfdc595012f
      [java] PWCallback: getUsage() = 1
      [java] 15:26:31,269 INFO - Verification successful for URI "#id-10357805"
      [java] Product Number/Comment: 605006/insufficient stock, 605002/in stock from WarehouseA, 605003/insufficient stock

In this scenario, the content of the SOAP Body of both the client request and the server response is signed and encrypted. The PWCallback: getUsage() = 3 entry in the output indicates that WSS4J uses the private key with the given identifier to generate a signature for the client request. After the client receives a response from the server, the PWCallback: getUsage() = 1 entry indicates that WSS4J uses the identified private key to decrypt the session symmetric key used by the server to encrypt the response.

Running Scenario C

Type the following command at a command prompt:
   % ant run-scc

If the client runs successfully, the output looks like the following:
   runclient:
      [echo] Running the ws.security.wss4j.ScenarioCClient program....
      [java] main:service URL=http://localhost:8060/wss4j/services/ScenarioC
      [java] 15:58:07,439 INFO - Using Crypto Engine [org.apache.ws.security.components.crypto.Merlin]
      [java] PWCallback: getIdentifier() = 1fb7623be7b2f4831ffc3f3741fa09dd_1e149434-9d3a-4adc-9284-4cfdc595012f
      [java] PWCallback: getUsage() = 3
      [java] 15:58:14,403 INFO - Using Crypto Engine [org.apache.ws.security.components.crypto.Merlin]
      [java] PWCallback: getIdentifier() = 1fb7623be7b2f4831ffc3f3741fa09dd_1e149434-9d3a-4adc-9284-4cfdc595012f
      [java] PWCallback: getUsage() = 1
      [java] 15:58:14,507 INFO - Verification successful for URI "#id-5854240"
      [java] Product Number/Comment: 605006/insufficient stock, 605002/in stock from WarehouseA, 605003/insufficient stock

In the client request, the contents of the <PartsOrder> element are sent in the clear, but the <custnbr> child of the <CustomerDetails> element is signed and encrypted. In the server response, the <submitOrderResponse> element, which is the only element in the SOAP Body, is signed and encrypted.

Sun JWSDP 1.5

The Java Web Services Developer Pack (JWSDP) from Sun Microsystems is an integrated toolkit that allows Java developers to develop, test, and deploy Web services. The JWSDP includes implementations of Web services standards including WSDL, SOAP, and UDDI. Sun includes an implementation of the WS-Security specification in JWSDP 1.5. The XML and Web Services Security (XWS-Security) framework enables Web services developers to sign/verify SOAP messages, encrypt/decrypt parts of messages, and perform user name/password-based authentication. Both XWS-Security and WSS4J use the Apache XML Security project's implementations of the XML Signature and XML Encryption specifications.

Like WSS4J, XWS-Security uses security configuration files to declaratively specify security constraints for the Web services client and server. To secure Web services using configuration files, XWS-Security adds a -security option to the JAX-RPC wscompile tool. The wscompile utility is used to generate client-side stubs, server-side ties, serializers, and WSDL files for JAX-RPC clients and services. Given the -security option with a security configuration file, wscompile generates the source code to implement the specified security mechanisms. This is an example of the code generated by wscompile in the client-side stub class PingPort_Ping_Stub from the JWSDP simple sample application. The security constraints are to sign and encrypt the SOAP Body of the request and to require that the SOAP Body of the response be signed and encrypted:

 private static com.sun.xml.rpc.security.SecurityPluginUtil secPgUtil;

 static {
      try {
         secPgUtil = new com.sun.xml.rpc.security.SecurityPluginUtil("[version EA3] <!-- Copyright 2004 Sun Microsystems, Inc. All rights reserved. SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. --> <xwss:JAXRPCSecurity xmlns:xwss=\"http://java.sun.com/xml/ns/xwss/config\"> <xwss:Service> <xwss:SecurityConfiguration dumpMessages=\"true\"> <xwss:Sign/> <xwss:Encrypt> <xwss:X509Token certificateAlias=\"s1as\" keyReferenceType=\"Identifier\"/> </xwss:Encrypt>
<!-- Requirements on messages received: --> <xwss:RequireEncryption/> <xwss:RequireSignature/> </xwss:SecurityConfiguration> </xwss:Service> <xwss:SecurityEnvironmentHandler> com.sun.xml.wss.sample.SecurityEnvironmentHandler </xwss:SecurityEnvironmentHandler> </xwss:JAXRPCSecurity>", "{http://xmlsoap.org/Ping}Ping", true);
      } catch (Exception e) {
         e.printStackTrace();
         throw new RuntimeException(e);
      }
 }

The Java Web Services Tutorial, available from Sun as a separate download, has a section that describes the syntax of the XWS-Security security configuration files. The files are written in XML, and the elements that specify an application's security mechanism(s) are enclosed within <xwss:SecurityConfiguration></xwss:SecurityConfiguration> elements. Within these declaration elements are child elements that specify the security features to apply to the SOAP message. The <xwss> elements can be listed sequentially so that more than one security mechanism can be applied to the SOAP message. For example, to first sign a message and then encrypt it, create an <xwss:Sign> element to do the signing, and then create an <xwss:Encrypt> element to encrypt after the signing.

JWSDP 1.5 introduced a new mandatory element in the XWS-Security configuration files called <xwss:SecurityEnvironmentHandler>. The value of this element is the name of a Java class that implements the javax.security.auth.callback.CallbackHandler interface and handles a set of callbacks defined by XWS-Security. An application uses a callback to obtain information related to security operations such as signing, encryption, and user name/password authentication. For example, an application can use a callback to look up an alias in a keystore or truststore, or a password in an authentication scheme. Both the Web services client and server must implement a SecurityEnvironmentHandler. The JWSDP simple application includes a SecurityEnvironmentHandler that implements all of the XWS-Security callbacks, except the UsernameCallback and the PasswordCallback.

Implementing the Sample Scenarios

Scenario A - Combine UsernameToken and Encryption

The Scenario A use case specifies that the client adds an encrypted UsernameToken to the Web service request. The XWS-Security configuration file to combine these two security actions on the client-side looks like this:

 <xwss:JAXRPCSecurity xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
    <xwss:Service>
       <xwss:SecurityConfiguration dumpMessages="true">
          <xwss:Timestamp timeout="120"/>
          <xwss:UsernameToken digestPassword="false"/>
          <xwss:Encrypt>
             <xwss:X509Token certificateAlias="s1as" keyReferenceType="Identifier"/>
             <xwss:Target type="qname">
{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}UsernameToken
             </xwss:Target>
          </xwss:Encrypt>
       <xwss:SecurityConfiguration>
    </xwss:Service>
    <xwss:SecurityEnvironmentHandler>
ws.security.jwsdp.ClientSecurityEnvironmentHandler
    </xwss:SecurityEnvironmentHandler>
 </xwss:JAXRPCSecurity>

The schema elements and their meanings are:

The <xwss:UsernameToken> can include the user's name and password in clear text. This example, however, uses the ws.security.jwsdp.ClientSecurityEnvironmentHandler Java class to retrieve the password from a system property at runtime. The class only implements the three callbacks required for this scenario - the UsernameCallback, the PasswordCallback, and the EncryptionKeyCallback. The handler throws an UnsupportedCallbackException for any other callbacks.

The server implementation of Scenario A leverages the JWSDP jaas-sample application. The Java Authentication and Authorization Service (JAAS) is a set of APIs that enable services to authenticate and enforce access controls upon users. The server-side ws.security.jwsdp.ServerSecurityEnvironmentHandler Java class uses a JAAS login module that authenticates the user name and password. The login() method in the com.sun.xml.wss.sample.UserPassLoginModule class references a flat-file XML database of user names and passwords to perform the authentication.

Scenario B - Combine Signature and Encryption

The Scenario B use case specifies that the client signs and then encrypts the SOAP Body of the request. The server decrypts the message and verifies the signature, and then signs and encrypts the SOAP Body of the response. The XWS-Security configuration file for the client-side of this scenario is:

 <xwss:JAXRPCSecurity xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
    <xwss:Service>
       <xwss:SecurityConfiguration dumpMessages="true">
          <xwss:Sign/>
          <xwss:Encrypt>
             <xwss:X509Token certificateAlias="s1as" keyReferenceType="Identifier"/>
          </xwss:Encrypt>
          <!--
           Requirements on messages received:
          -->
          <xwss:RequireEncryption/>
          <xwss:RequireSignature/>
       <xwss:SecurityConfiguration>
    </xwss:Service>
    <xwss:SecurityEnvironmentHandler>
com.sun.xml.wss.sample.SecurityEnvironmentHandler
    </xwss:SecurityEnvironmentHandler>
 </xwss:JAXRPCSecurity>

The schema elements and their meanings are:

Scenario C - Signing and Encrypting a Single XML Element

The Scenario C use case specifies that the client signs and then encrypts a single XML element in the SOAP request body. The server decrypts the element and verifies the signature, and then signs and encrypts an XML element in the response. The XWS-Security <xwss:Target> subelement of the <xwss:Sign> and <xwss:Encrypt> elements identifies which SOAP element to sign or encrypt.

 <xwss:JAXRPCSecurity xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
    <xwss:Service>
       <xwss:SecurityConfiguration dumpMessages="true">
          <xwss:Sign>
             <xwss:X509Token certificateAlias="xws-security-client" keyReferenceType="Direct"/>
             <xwss:Target type="qname">CustomerDetails</xwss:Target>
          </xwss:Sign>
          <xwss:Encrypt>
             <xwss:X509Token certificateAlias="s1as" keyReferenceType="Identifier"/>
             <xwss:Target type="qname">CustomerDetails</xwss:Target>
          </xwss:Encrypt>
          <!--
           Requirements on messages received:
          -->
          <xwss:RequireEncryption>
             <xwss:Target type="xpath">//*[local-name()='Item' and contains(.,'605003')]</xwss:Target>
          </xwss:RequireEncryption>
          <xwss:RequireSignature>
             <xwss:Target type="xpath">//*[local-name()='Item' and contains(.,'605003')]</xwss:Target>
          </xwss:RequireSignature>
       <xwss:SecurityConfiguration>
    </xwss:Service>
    <xwss:SecurityEnvironmentHandler>
com.sun.xml.wss.sample.SecurityEnvironmentHandler
    </xwss:SecurityEnvironmentHandler>
 </xwss:JAXRPCSecurity>

Most of the schema elements are familiar from discussions of the previous scenarios. The interesting elements and their meanings are:

Running the Sample Application

Java Web Services Developer Pack can be downloaded from Sun's web site for Web services. JWSDP 1.5 became available in November 2004, and older releases are also still available.

The sample code for the WS-Security scenarios is in the jwsdpUtil directory. Here is an overview of the contents of the directory:

build/client
Java source code and classes generated by wscompile, and the Java object class(es) built by the ant target compile-client.
build/common
Java object classes for the SecurityEnvironmentHandler implementation used by the Web services client and server, built by the ant target compile-handler-code.
build/server
Java source code and classes generated by wscompile and the Java object class(es) built by the ant target compile-server.
build/war
Web application built by the ant target make-war, which runs the Sun wsdeploy tool.
client/ws/security/jwsdp
Java source code for the scenario client and the SecurityEnvironmentHandler used in Scenario A.
common
Java source code for the SecurityEnvironmentHandler used by the Web services client and server in Scenario B and Scenario C.
config/keystores
Client keystore and truststore files from the <jwsdp.home>/xws-security/etc directory of the JWSDP distribution. Used by the scenario client.
etc
Sun-proprietary files read by the wsdeploy tool to create a Web services WAR file. The deployment descriptor, jaxrpc-ri.xml, is bundled in a "raw" WAR file and used by wsdeploy to generate the "cooked" WAR file. This descriptor provides information to wsdeploy required for deploying the Web service to the Web container.
etc/security
Security configuration files used by the Web service and scenario clients. These files are specified as values for the -security option to wscompile.
server
Java source code for the Web service implementation and the server-side code for JAAS authentication used in Scenario A.
wsdl
WSDL and XML Schema files for the Retailer Web service from the WS-I. Also contains the wscompile-config.xml file used by wscompile.
Setting Up The Sample Application

In addition to JWSDP, several other downloads are required to run the sample application. The JWSDP installer prompts you to select or download a Web container that will host JWSDP Web applications. The three supported containers are the Java System Application Server Platform Edition 8.0, the Java System Web Server 6.1 Service Pack 3, and Apache Jakarta Tomcat 5.0, and are available from Sun's container downloads page. We tested with the Tomcat container. The JWSDP installer adds JAR files and sample JWSDP Web applications to the standard Tomcat release. JWSDP includes instructions and a script to reconfigure a standard Tomcat download, but after a modest effort to use them failed, we used the installer to configure the Tomcat instance downloaded from Sun.

A Java Cryptography Extension (JCE) provider for J2SE 1.4 also must be available to run the JWSDP XWS-Security sample applications and this sample application. A JCE provider is required because the provider included with JDK 1.4.x does not support RSA encryption. The <jwsdp.home>/xws-security/samples/simple/README.txt file has a URL for a list of providers and instructions on how to install the provider JAR file in the JRE. We used a JCE provider from Bouncy Castle.

Note that we used the keystore and truststore certificates supplied with the XWS-Security samples. If you intend to generate your own test certificates, keytool (the default tool for creating, importing, and exporting certificates) can not be used. That is because keytool only creates X.509v1 certificates. The WS-Security X.509 Token Profile specifies X.509 version 3 certificates can be used for digital signatures and encryption. You can use another tool, such as openssl, to generate an X.509v3 certificate, and then use the pkcs12import tool provided with JWSDP to import the certificate into a Java keystore.

Scenario A demonstrates user name/password based authentication. The JAAS login module uses an XML file that lists the set of valid user names along with their passwords. The Sun installer adds the userpasslist.xml file to the <tomcat.home>/xws-security/etc directory. JAAS authentication also uses a LoginContext that specifies an application name, which is used to identify the list of LoginModules configured for the application. The Scenario A application name is SCENARIOA_SECURITY_SERVER. Edit the <tomcat.home>/xws-security/server-config.jaas file and add this entry:

   SCENARIOA_SECURITY_SERVER {
      com.sun.xml.wss.sample.UserPassLoginModule REQUIRED debug=true;
   };

Several of the properties in the jwsdpUtil/build.properties file need to be configured specifically for your system. Find the following properties and set the correct values for your system:

# java (for wscompile -fork and wsdeploy)
javahome=<directory_location_of_your_J2SE_installation>

# place where JWSDP is installed
jwsdp.home=<directory_location_of_your_JWSDP_installation>

# container home
tomcat.home=<directory_location_of_your_Tomcat_installation>

# Replace username and password values with the admin user/password
# for the appropriate container instance being used for this sample
username=admin
password=admin123

# the host and port for the server endpoint
endpoint.host=localhost
endpoint.port=8080

Running the Scenarios

The steps to run the scenarios with JWSDP differ from the other toolkits because the security constraints specified in the wscompile step are embedded in the generated Java source code. Therefore, rebuild both the client and server code before you run a given scenario. Then deploy the server-side WAR file to the Tomcat container. Start the Tomcat container before building and deploying the code for each scenario as described below. To run Tomcat in the foreground so that the console output is visible, type the following command from your Tomcat installation directory:
   % bin/catalina.sh run

Running the Retailer Web Service without WS-Security Constraints

Type the following commands at a command prompt:
   % ant example
   % ant deploy-tomcat
   % ant run-client

If the client runs successfully, the output looks like the following:
   run-client:
      [echo] Running the ws.security.jwsdp.RetailerClient program....
      [java] Service URL=http://localhost:8080/wssretailer/Retailer
      [java] Product Number/Comment: 605006/insufficient stock, 605002/in stock from WarehouseA, 605003/insufficient stock

Running Scenario A

Type the following commands at a command prompt:
   % ant scenarioA
   % ant deploy-tomcat
   % ant run-client

If the client runs successfully, the output looks like the following:
   run-client:
      [echo] Running the ws.security.jwsdp.RetailerClient program....
      [java] Service URL=http://localhost:8080/wssretailer/Retailer
      [java] Dec 3, 2004 1:35:11 PM com.sun.xml.wss.filter.DumpFilter process
      [java] INFO: ==== Sending Message Start ====
      ...
      [java] ==== Sending Message End ====
      [java] Dec 3, 2004 1:35:25 PM com.sun.xml.wss.filter.DumpFilter process
      [java] INFO: ==== Received Message Start ====
      ...
      [java] ==== Received Message End ====
      [java] Dec 3, 2004 1:35:25 PM com.sun.xml.wss.filter.ProcessSecurityHeaderFilter process
      [java] WARNING: Message does not contain wsse:Security header
      [java] Product Number/Comment: 605006/insufficient stock, 605002/in stock from WarehouseA, 605003/insufficient stock

For all the scenarios, the dumpMessages attribute of the <xwss:SecurityConfiguration> element is set to true in both the client and the server security configuration files. When dumpMessages is set to true, all incoming and outgoing SOAP messages are printed to the standard output. The user name and password are encrypted in the SOAP header in the <wsse:Security> element of the client request. A warning appears on the received message because the server sends a reply without any security features.

Running Scenario B

Type the following commands at a command prompt:
   % ant scenarioB
   % ant deploy-tomcat
   % ant run-client

If the client runs successfully, the output looks like the following:
   run-client:
      [echo] Running the ws.security.jwsdp.RetailerClient program....
      [java] Service URL=http://localhost:8080/wssretailer/Retailer
      [java] Dec 3, 2004 1:45:11 PM com.sun.xml.wss.filter.DumpFilter process
      [java] INFO: ==== Sending Message Start ====
      ...
      [java] ==== Sending Message End ====
      [java] Dec 3, 2004 1:45:25 PM com.sun.xml.wss.filter.DumpFilter process
      [java] INFO: ==== Received Message Start ====
      ...
      [java] ==== Received Message End ====
      [java] Dec 3, 2004 1:45:25 PM com.sun.xml.wss.filter.ProcessSecurityHeaderFilter process
      [java] Product Number/Comment: 605006/insufficient stock, 605002/in stock from WarehouseA, 605003/insufficient stock

In this scenario, the content of the SOAP Body of the client request and the server response is signed and encrypted.

Running Scenario C

Type the following commands at a command prompt:
   % ant scenarioC
   % ant deploy-tomcat
   % ant run-client

If the client runs successfully, the output is displayed to standard output as in the previous scenarios. In the client request, the contents of the <PartsOrder> element are sent in the clear but the <CustomerDetails> element and its children are signed and encrypted. In the server response, the third element of the array of <Item> elements, which has a <productNumber> subelement with a string value of 605003, is signed and encrypted.

webMethods Glue 5.0.2

webMethods Glue is a Java-based platform for creating, deploying, managing, and invoking Web services. A goal of Glue's developers has been to build a Web services platform with a simple conceptual model and an easy-to-understand API. Glue can readily expose Java objects as Web services without requiring changes to the code. Glue can used in one of two modes. In standalone mode, Glue provides a lightweight, high-performance application server with a Web server, servlet engine, JSP engine, and XML parser. In hosted mode, Glue can be deployed as a servlet into a third party container such as WebLogic, Tomcat, or JBoss. In hosted mode, the container assumes the processing of HTTP requests, servlets, and JSPs, leaving Glue to process SOAP and WSDL requests.

WS-Security constraints can be specified either by using declarative service descriptors in a Glue application or by adding calls to the Glue security API to the Web service provider and client source code. To create a Glue application, use the newapp utility to create a skeleton J2EE application. XML service descriptors for Web services are added to the WEB-INF/services directory in the application. The descriptors can have <wssAuthenticate>, <wssSignature>, and <wssEncryption> elements that define the security constraints for the Web service. Clients can hardcode security specifications using the Glue security API or add <signatureTemplate> and/or <encryptionTemplate> elements to the client-side configuration file.

Implementing the Sample Scenarios

Scenario A - Combine UsernameToken and Encryption

The Scenario A use case specifies that the client adds an encrypted UsernameToken to the Web service request. The client must use the Glue security API to attach a token to the request:

    // set up the WS-Security context
ProxyContext proxyContext = new ProxyContext();
WSSContext wss = new WSSContext();
proxyContext.setWSSContext(wss);

// add a UsernameToken to each outgoing request
String username = System.getProperty("scenarioA.username");
String password = System.getProperty("scenarioA.password");
UsernameToken usernameToken = new UsernameToken(
username,
password,
IWSSConstants.PASSWORD_DIGEST,
true);
wss.out.addSecurityToken(usernameToken);

In this example, the client adds a UsernameToken and specifies that the password is sent as a digest hash rather than being sent as clear text. Glue does not provide a means to encrypt the <UsernameToken> element in the SOAP WS-Security header block. An email from Glue technical support explained that the implementation of the security API does not correctly utilize all the namespaces specified in the Glue ElementReference class. The XPath expression for the WS-Security <UsernameToken> element references the WS-Security namespace, and the element isn't encrypted because of the flaw in the code. Sending the password as a hash adds somewhat more security because the password is sent as base64-encoded SHA1 (Secure Hashing Algorithm) hash value.

On the server-side, a service descriptor called scenarioA.xml in the WEB-INF/services directory includes a <wssAuthenticate> element:

 <!--check ws-security tokens for a valid role--> 
<wssAuthenticate>
<realm>acl</realm>
<role>customer</role>
</wssAuthenticate>

The <wssAuthenticate> element in the service descriptor refers to the acl realm, so the configuration file WEB-INF/glue-config.xml must have a <realm> named acl in the AUTHENTICATION section.

 <!--list of realms, used by security guards to authenticate clients--> 
<realm>
<constructor>
<args>
<name>acl</name>
<path>security\acl.xml</path>
</args>
</constructor>
</realm>

Finally, the WEB-INF/security/acl.xml file must have an entry with a user's name, password, and role. The server is now configured to require that a client of the service provides a valid user name and password with a service request.

Scenario B - Combine Signature and Encryption

The Scenario B use case specifies that the client signs and then encrypts the SOAP Body of the request. The server decrypts the message and verifies the signature, and then signs and encrypts the response. Unlike WSS4J and XWS-Security, this version of Glue does not dynamically generate symmetric encryption keys. Instead, both the client and server agree to use the same symmetric key to both encrypt and decrypt data. webMethods technical support indicates that Glue 6.0, targeted for release in February 2005, dynamically generates symmetric keys.

Processing the Web Services Request

Glue clients can use templates to declaratively specify their signature and encryption requirements. The client-side scenarioA-client.xml file for this scenario is:

 <wsSecurity>
<!--template that specifies that outgoing soap requests-->
<!--have the entire soap body element signed-->
<signatureTemplate>
<name>ScenarioBExampleSignature</name>
<reference>soap:Envelope/soap:Body</reference>
<keyStore>clientcert.jks</keyStore>
<keyStorePassword>changeit</keyStorePassword>
<alias>test</alias>
</signatureTemplate>

<!--template that specifies encryption of the body-->
<!--contents of outgoing soap requests with the given-->
<!--user and key-->
<encryptionTemplate>
<name>ScenarioBEncryptionTemplate</name>
<reference>soap:Envelope/soap:Body/*</reference>
<secretKey>
<user>crypto</user>
<base64Key>qB+Jkl0sTHolHAL0ZKv7hqgfiZJdLEx6</base64Key>
</secretKey>
</encryptionTemplate>
</wsSecurity>

The interesting <signatureTemplate> schema elements and their meanings are:

The interesting <encryptionTemplate> schema elements and their meanings are:

The client references these templates to specify that requests be signed and encrypted:
    // set up the WS-Security context
ProxyContext proxyContext = new ProxyContext();
WSSContext wss = new WSSContext();
proxyContext.setWSSContext(wss);

// sign and encrypt each outgoing request
wss.out.addSignature(new WSSSignature("ScenarioBExampleSignature"));
wss.out.addEncryption(new WSSEncryption("ScenarioBEncryptionTemplate"));

Glue Web services applications also can specify their signature and encryption constraints declaratively in a service descriptor. Here are the property entries in the WEB-INF/services/scenarioB.xml service descriptor that correspond to the client configuration described above:

   <!--check incoming messages for ws-security signature on message body-->
<wssSignature>
<reference>soap:Envelope/soap:Body</reference>
<trustStore>clientcert</trustStore>
<trustStorePassword>changeit</trustStorePassword>
</wssSignature>

<!--ensure that the body contents of incoming soap-->
<!--requests are encrypted using a secret key from-->
<!--the acl realm-->
<wssEncryption>
<reference>soap:Envelope/soap:Body/*</reference>
<secretKey>
<realm>acl</realm>
</secretKey>
</wssEncryption>

In addition, an entry for the crypto user with a password of the base64-encoded key must be added to the application WEB-INF/security/acl.xml file.

Processing the Web Services Response

As described above, Glue Web services applications can use XML service descriptors to configure signature and encryption constraints on incoming requests. To apply signatures and encryption to outgoing responses, however, the service provider has to use the Glue programmatic API. This example shows how a server can add a signature and encryption to an outgoing response. Unlike the Scenario A example, the Scenario B Web service does not run inside the Glue application framework. Instead, the Scenario B Web service uses an in-process Glue Web server to accept incoming HTTP requests and the Glue publish() method to publish the Java class as a Web service.

The example shows how a server can sign and encrypt the SOAP Body of the outgoing message using the Glue APIs.

  {
// set up the WS Security context
WSSContext wss = new WSSContext();
ServiceContext serviceContext = new ServiceContext();
serviceContext.setWSSContext(wss);

// sign the SOAP Body of an outgoing message
KeyStore keyStore = loadKeyStore("clientcert", "changeit");
PrivateKey privateKey = (PrivateKey)keyStore.getKey("test", "changeit".toCharArray());
X509Certificate cert = (X509Certificate)keyStore.getCertificate("test");

// define an element to sign the SOAP body
ElementReference sigRef = new ElementReference("soap:Envelope/soap:Body");
WSSSignature outSignatureSpec = new WSSSignature(sigRef);
outSignatureSpec.setCertificate(cert);
outSignatureSpec.setPrivateKey(privateKey);
wss.out.addSignature(outSignatureSpec);

// encrypt the SOAP Body of an outgoing message
WSSEncryption outEncryptionSpec = new WSSEncryption();
ElementReference encRef = new ElementReference("soap:Envelope/soap:Body/*");
outEncryptionSpec.setReference(encRef);
outEncryptionSpec.setKeyName("crypto");
byte[] secretKeyBytes = Base64.fromBase64("qB+Jkl0sTHolHAL0ZKv7hqgfiZJdLEx6");
outEncryptionSpec.setSecretKeyBytes(secretKeyBytes);
wss.out.addEncryption(outEncryptionSpec);
...
Registry.publish("scenarioB", new RetailerPortTypeImpl(), serviceContext);
}

private static KeyStore loadKeyStore(String keystoreFile, String password)
throws Exception {
KeyStore ks = KeyStore.getInstance( "JKS" );
FileInputStream fis = new FileInputStream(keystoreFile);
ks.load(fis, password.toCharArray());
return ks;
}

The server creates a WSSContext (WS-Security Context) class. The context is used to set the signature and encryption properties for the Web service. The WSSSignature class contains the information about the X.509 certificate and private key used the sign the SOAP Body XML element. The WSSEncryption class has the symmetric key used to encrypt the SOAP Body. The signature and encryption specifications are added to the security context for outgoing messages.

The Scenario B client specifies signature and encryption guards to process the Web services response. The client can leverage the same signature template it used to sign the outgoing message to specify a signature guard for the incoming response. To configure an encryption guard for the response, however, the client must use the Glue security APIs.

Here's an example of the client-side code to decrypt and authenticate the incoming response message:

    // set up the WS Security context
WSSContext wss = new WSSContext();
ProxyContext proxyContext = new ProxyContext();
proxyContext.setWSSContext(wss);
...

// decrypt and authenticate the incoming response message

// create the encryption spec for the SOAP body
BasicRealm wssRealm = new BasicRealm("wss");
String username = "crypto";
String password = "qB+Jkl0sTHolHAL0ZKv7hqgfiZJdLEx6";
wssRealm.addPrincipal(username, password);
Realms.addRealm(wssRealm);

ElementReference encRef = new ElementReference("soap:Envelope/soap:Body/*");
WSSEncryption encryptionSpec = new WSSEncryption();
encryptionSpec.setReference(encRef);
encryptionSpec.setRealm(wssRealm);

// add the encryption and signature guards
wss.in.addGuard(new EncryptionGuard(encryptionSpec));
wss.in.addAuthenticator(new X509NullAuthenticator());
wss.in.addGuard(new SignatureGuard(new WSSSignature("ScenarioBExampleSignature")));

In this example, the client adds signature and encryption constraints that are typically associated with the Web service provider. The client creates a WSSContext (WS-Security Context) class. The context is used to set the signature and encryption properties for the client call to the Web service. The client creates a BasicRealm class and adds a principal with a user name and password that match the symmetric-key values. The WSSEncryption class has information about the realm and the XML element to decrypt.

The client uses the X509NullAuthenticator as an authenticator. This authenticator allows any valid certificate to pass through. The Web service provider uses the more secure X509Authenticator class, which has information about a keystore and its certificates. An incoming request that is not signed by a certificate in the key store is rejected. The client applies the signature and encryption guards to the incoming message, which intercept and validate the message before passing it to the client.

Scenario C - Signing and Encrypting a Single XML Element

The Scenario C use case specifies that the client signs and then encrypts a single XML element in the SOAP request body. The server decrypts the element and verifies the signature, and then signs and encrypts the response.

The Glue WS-Security samples include an example of a client encrypting a single element in the SOAP Body of a request. In the example, the client uses an encryption template with a <reference> element defined as:

  <reference>
soap:Envelope/soap:Body/getRate/country1
</reference>

In the Glue example, neither the <getRate> or the <country1> elements in the SOAP Body have namespace prefixes. When Glue generates the XML document for the submitOrder() operation used in the scenarios, however, each XML element has a namespace prefix. The prefixes and their corresponding namespaces must be set in the Glue ElementReference class to create the XPath expression for an element. As described in Scenario A, the current implementation of the security APIs does not correctly utilize all the specified namespaces.

A workaround for the code flaw is to use an XPath expression that does not use namespaces to specify an XML element. We used an XPath expression with that syntax in Scenario C with Sun's JWSDP. The XPath local-name() function can be used to select elements without specifying their namespaces. As in Scenario B, Glue clients can use templates to declaratively specify their signature and encryption requirements. The client-side scenarioC-client.xml file for this scenario is:

 <wsSecurity>
<!--template that specifies that outgoing soap requests-->
<!--have the customerDetails soap body element signed-->
<signatureTemplate>
<name>ScenarioCRequestSignature</name>
<reference>//*[local-name()='customerDetails']</reference>
<keyStore>clientcert.jks</keyStore>
<keyStorePassword>changeit</keyStorePassword>
<alias>test</alias>
</signatureTemplate>

<!--template that specifies encryption of the customerDetails-->
<!--element of outgoing soap requests with the given-->
<!--user and key-->
<encryptionTemplate>
<name>ScenarioCRequestEncryption</name>
<reference>//*[local-name()='customerDetails']</reference>
<secretKey>
<user>crypto</user>
<base64Key>qB+Jkl0sTHolHAL0ZKv7hqgfiZJdLEx6</base64Key>
</secretKey>
</encryptionTemplate>

<!--template that specifies that incoming soap responses-->
<!--have a soap body element signed-->
<signatureTemplate>
<name>ScenarioCResponseSignature</name>
<reference>//*[local-name()='PartsOrderResponseItem' and contains(.,'605003')]</reference>
<keyStore>clientcert.jks</keyStore>
<keyStorePassword>changeit</keyStorePassword>
<alias>test</alias>
</signatureTemplate>
</wsSecurity>

Most of the schema elements are familiar from the discussion of Scenario B. The interesting elements and their meanings are:

The Scenario C client specifies signature and encryption guards to process both the Web services request and response. Therefore, the client's configuration file has two different signature templates. One is used to sign the outgoing message, and the other to specify a signature guard for the incoming response. The client must use the Glue security APIs, however, to configure an encryption guard for the response.

The same Java source code implements the Web service for both Scenario B and Scenario C. The code obtains XPath expressions for the XML elements to sign and encrypt from Java system properties. [Note: the server source code example in the discussion of Scenario B in this paper uses hard-coded values for the XPath expressions for signature and encryption elements for clarity and readability. The actual Java source code gets these values from system properties.]

Running the Sample Application

Contact webMethods to obtain a copy of Glue Professional. webMethods distributes three editions of Glue: Standard, Professional, and Enterprise. Glue Standard Edition, which can be downloaded from webMethods, does not include support for WS-Security. Glue Professional Edition does include support, and we used that edition. webMethods provides an evaluation license that expires after 30 days.

The sample code for the WS-Security scenarios is in the glueUtil directory. Here is an overview of the contents of the directory:

bin
Shell scripts that set Glue environment variables, run the Glue application server for Scenario A, and run Glue in-process servers for Scenario B and Scenario C.
build/classes
Java object classes built by the ant target compile.
build/glueApp
Glue application for Scenario A built by the ant target make-war, which runs the Glue newapp utility.
config/clients
Glue configuration files for the Scenario B and Scenario C clients.
config/keystores
Self-signed X.509 certificate generated by the JDK keytool utility. Used by the scenario clients and Web services.
config/maps
A file that contains an annotated XML schema that describes how XML types are mapped to their Java equivalents. Generated by the ant target gen-classes, which runs the Glue wsdl2java utility.
config/servers
Java property files for the Scenario B and Scenario C servers.
ws/security/glue
Java source code for the implementation of the Web service and the scenario clients.
ws/security/glueclient
Java source code generated by the ant target gen-classes, which runs the Glue wsdl2java utility.
WEB-INF/security
File that contains the access control list for the Glue application.
WEB-INF/services
Files containing the XML service descriptors of the Web services published in the Glue application.
wsdl
WSDL and XML Schema files for the Retailer Web service from the WS-I. I had to modify the Configuration.xsd schema file to prevent wsdl2java from throwing this exception:
electric.xml.io.schema.SchemaException: could not find a electric.xml.io.schema.SchemaEntry with qname http://schemas.xmlsoap.org/soap/envelope/:mustUnderstand.

Running the Scenarios

The GLUE_HOME environment variable in the glueUtil/bin/glueEnv.sh file needs to be configured specifically for your system. Find the entry and set the correct value for your system:

if [ -z "$GLUE_HOME" ]; then
GLUE_HOME=<directory_location_of_your_Glue_installation>
fi

Several of the properties in the glueUtil/build.properties file need to be configured specifically for your system. Find the following properties and set the correct values for your system:

# place where Glue is installed
glue.home=<directory_location_of_your_Glue_installation>

# the host for the server endpoint
endpoint.host=localhost

Type the following commands at a command prompt to build the code for the Glue samples:
   % ant gen-classes
   % ant make-war

To see a list of useful ant targets, type the command:
   % ant help

Running the Retailer Web Service without WS-Security Constraints

  1. From the glueUtil directory, type the following at a command prompt to start the Glue application server:
       % bin/glueApp.sh

    This command starts the Glue application server on the default port of 8004. If the server runs successfully, the output looks like the following:
          [STARTUP] Glue Professional 5.0.2 build 77 (c) 2001-2004 webMethods, Inc.
          evaluation expires on 12/15/04
          [STARTUP] web server started on http://192.168.13.16:8004
          [STARTUP] soap/http server started on http://192.168.13.16:8004/glueApp/services

    The verbosity of the output from the Glue application server is configured in the <logging> section of the application's WEB-INF/glue-config.xml file. The SECURITY, SECURITY_DETAIL, and SECURITY_DEBUG logging categories are turned on.

  2. Type the following command at a command prompt to run the Web service client without any security constraints:
       % ant run-example

    If the client runs successfully, the output looks like the following:
       run-example:
          [echo] Running the ws.security.glue.RetailerClient program....
          [java] Service URL=http://localhost:8004/glueApp/services/retailer.wsdl
          ...
          [java] Product Number/Comment: 605006/insufficient stock, 605002/in stock from WarehouseA, 605003/insufficient stock

    The verbosity of the output from the Glue client is configured by the <electric.logging> property. The SOAP and RESOURCES logging categories are turned on. The SOAP category displays the SOAP messages for both the client request and the server response.

Running Scenario A
  1. If the Glue application server is not already running, type the following at a command prompt from the glueUtil directory to start it:
       % bin/glueApp.sh

  2. Type the following command at a command prompt to run the Scenario A client:
       % ant run-sca

    If the client runs successfully, the output looks like the following:
       run-sca:
          [echo] Running the ws.security.jwsdp.ScenarioAClient program....
          ...
          [java] [SOAP] request to http://192.168.13.16:8004/glueApp/services/scenarioA
          ...
          [java] [SOAP] response from http://192.168.13.16:8004/glueApp/services/scenarioA
          ...
          [java] Product Number/Comment: 605006/insufficient stock, 605002/in stock from WarehouseA, 605003/insufficient stock

    The WS-Security UsernameToken with a hashed password is displayed in the SOAP header in the <wsse:Security> element of the client request.

    Running Scenario B

    Glue Web services applications and clients can declaratively specify their signature and encryption constraints in service descriptor files. To apply signatures and encryption to the outgoing response, however, the service provider has to use the Glue programmatic APIs. Unlike the Scenario A example, the Scenario B Web service does not run inside the Glue application framework. Instead, the Scenario B Web service uses an in-process Glue Web server to accept incoming Web services requests.

    1. From the glueUtil directory, type the following at a command prompt to start the Scenario B Glue Web server:
         % bin/scenarioBServer.sh

      This command starts the service on port 8014. If the server runs successfully, the output looks like the following:
            ...
            Service URL=http://localhost:8014/glue/services
            ...

    2. Type the following command at a command prompt to run the Scenario B client:
         % ant run-scb

      If the client runs successfully, the output looks like the following:
         run-scb:
            [echo] Running the ws.security.glue.ScenarioBClient program....
            [java] Service URL=http://localhost:8014/glue/services/scenarioB.wsdl
            ...
            [java] [SOAP] request to http://192.168.13.16:8014/glue/services/scenarioB
            ...
            [java] [SOAP] response from http://192.168.13.16:8014/glue/services/scenarioB
            ...
            [java] Product Number/Comment: 605006/insufficient stock, 605002/in stock from WarehouseA, 605003/insufficient stock

      In this scenario, the content of the SOAP Body of the client request and the server response is signed and encrypted.

    Running Scenario C

    Like the Scenario B example, the Scenario C Web service uses an in-process Glue Web server to accept incoming Web services requests.

    1. From the glueUtil directory, type the following at a command prompt to start the Scenario C Glue Web server:
         % bin/scenarioCServer.sh

      This command starts the service on port 8024. If the server runs successfully, the output looks like the following:
            ...
            Service URL=http://localhost:8024/glue/services
            ...

    2. Type the following command at a command prompt to run the Scenario C client:
         % ant run-scc

      If the client runs successfully, the output looks like the following:
         run-scc:
            [echo] Running the ws.security.glue.ScenarioCClient program....
            [java] Service URL=http://localhost:8024/glue/services/scenarioC.wsdl
            ...
            [java] [SOAP] request to http://192.168.13.16:8024/glue/services/scenarioC
            ...
            [java] [SOAP] response from http://192.168.13.16:8024/glue/services/scenarioC
            ...
            [java] Product Number/Comment: 605006/insufficient stock, 605002/in stock from WarehouseA, 605003/insufficient stock

      In the client request, the contents of the <partsOrderList> element are sent in the clear but the <customerDetails> element and its children are signed and encrypted. In the server response, the third element of the array of <PartsOrderResponseItem> elements, which has a <productNumber> subelement with a string value of 605003, is signed and encrypted.

    Interoperability of WS-Security Toolkits

    The OASIS Web Services Security Technical Committee (WSS TC) authored documents that list scenarios to be used to test interoperability between implementations of the WS-Security specification. The scenarios describe the Web service request and response SOAP messages and the general flow of the messages. The scenarios are intended to test the interoperability of different implementations and are not designed to represent reasonable or practical applications of the specifications. All seven scenarios use the same simple Ping Web service application. The client sends a <Ping> element with a string value, and the service returns a <PingResponse> element with the same string value.

    Scenario
    Description
    Scenario #1
    The Request header contains a user name and a plaintext password. The Response does not contain a security header.
    Scenario #2
    The Request header contains a user name and password that have been encrypted using a public key provided out-of-band. The Response does not contain a security header.
    Scenario #3
    The Request body contains data that has been signed and encrypted. The certificate used to verify the signature is provided in the header. The certificate associated with the encryption is provided out-of-band. The Response body is also signed and encrypted, reversing the roles of the key pairs identified by the certificates.
    Scenario #4
    The Request body contains data that has been signed and encrypted. The certificate used to verify the signature is provided in the header. The symmetric key used to perform the encryption is provided out-of-band. The Response body is also signed and encrypted. The same symmetric key is used to perform the encryption. The certificate used to verify the signature is provided out-of-band.
    Scenario #5
    The Request body contains data that has been signed twice. First the first element of the body is signed. The certificate used to verify this signature is provided out-of-band. Next the entire body is signed. The certificate used to verify this signature is provided in the header. The Response body is not signed or encrypted.
    Scenario #6
    The Request body contains data that has been encrypted and signed. The certificate associated with the encryption is provided out-of-band. The certificate used to verify the signature is provided in the header. The Response body is also encrypted and signed, reversing the roles of the key pairs identified by the certificates.
    Scenario #7
    The Request body contains data that has been signed and encrypted. The signature also protects an enclosed security token by means of the STR Dereference Transform. The certificate used to verify the signature is provided in the header. The certificate associated with the encryption is provided out-of-band. The Response body is also signed and encrypted, reversing the roles of the key pairs identified by the certificates.

    Apache WSS4J includes samples of the interoperability scenarios, and posts to the Apache JIRA WS-FX issue tracker state that WSS4J is interoperable with Microsoft .NET, IBM WebSphere, and BEA WebLogic. The webMethods Glue toolkit does not include interoperability samples. Sun JWSDP 1.4 has an interop sample application, however, it is not included with JWSDP 1.5.

    Glue cannot interoperate with the other toolkits because of the definition of the wsse namespace. Glue uses a definition of the namespace that interoperates with Microsoft's WSE 1.0:

    xmlns:wsse='http://schemas.xmlsoap.org/ws/2002/12/secext'

    WSS4J and JWSDP define the namespace as:

    xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'

    The definition used by WSS4J and JWSDP is the OASIS WS-Security 1.0 namespace. webMethods technical support indicates that Glue 6.0, available in February 2005, has the updated namespace. WSS4J can be configured to use namespaces from older OASIS specifications, however, we did not test that capability.

    We had qualified success testing interoperability between the WSS4J and JWSDP implementations. WSS4J includes an ant target interop-war that builds a Web application that can be used for interoperability testing. The Web application includes deployment descriptors for both the scenario clients and servers. Leveraging the security configuration files included with the JWSDP sample application, we created JWSDP client and server configuration files for the OASIS interoperability scenarios. We used X.509 certificates from the interop.jks keystore included with WSS4J for the clients and servers in both toolkits.

    With a caveat, WSS4J and JWSDP exchanged request/response messages for five of the OASIS interoperability scenarios: Scenario #1 - Scenario #3, Scenario #5, and Scenario #6. We did not test Scenario #4, which requires a symmetric encryption key, and are not able to find documentation in JWSDP for a "STR Dereference Transform," required by Scenario #7. The caveat is that the toolkits did not correctly process the <wsu:Timestamp> element that is a child of the <wsse:Security> header. The WSS4J server did not recognize the <wsu:Timestamp> element in a JWSDP request.

    We edited the server-config.wsdd file in the WSS4J Web application and deleted Timestamp from the action parameter list for services. The WSS4J server then accepted JWSDP requests. We also modified timestamp specifications in the JWSDP security configuration files. By default, JWSDP includes timestamps with outgoing signatures and requires timestamps on incoming signatures. The WSS4J server generates an exception when a JWSDP client request includes signatures with timestamps. We also defined the JWSDP security constraints so that signatures in response messages do not require timestamps.

    Summary

    This paper presents an introduction to message security requirements and the WS-Security specification. We describe three use cases that utilize the security features provided by WS-Security. We then report our attempts to implement those scenarios using the Apache WSS4J, Sun JWSDP, and webMethods Glue toolkits. We also test the interoperability of the toolkits' implementations of the WS-Security specification.

    The Apache WSS4J implementation leverages the Apache Axis handler architecture. This provides the benefit of being able to declaratively specify security constraints for both the Web services provider and client in deployment descriptors. Another benefit of this design is that the security requirements for Web services are distinct and separate from business logic. Security features can be added to a Web service and client with minimal impact to existing code. The developer can focus on the application logic, and a security domain expert can define the properties to secure the service.

    The XWS-Security implementation in JWSDP also uses configuration files to declaratively specify security constraints for both the Web services provider and client. This approach maintains the clean separation between security requirements and business logic. Unlike the WSS4J implementation, however, the security configuration files are referenced at compile-time rather than run-time. The wscompile utility inserts code that implements the security features into the client stubs and server ties it generates. The developer has to recompile the code when the security requirements change.

    webMethods Glue uses a combination of declarative service descriptors and calls to the Glue security APIs to specify security constraints. Glue clients can use templates in configuration files to define signature and encryption requirements. The client then references the templates in source code to apply the constraints. Web services deployed in a Glue application can also use templates to define security requirements for incoming requests. To apply signatures or encryption to outgoing responses, however, the provider has to use the Glue security APIs. The client is also required to use the security APIs to process response messages. The developer must modify the source code when changes are made to security requirements.

    We had limited success testing the interoperability of the three toolkits. This can partly be attributed to the fact that the WS-Security specification was ratified as a standard only within the past year. Apache WSS4J is in an "incubation" phase of the Apache Software Foundation process, needing to demonstrate the infrastructure and stability of successful Apache projects. Sun JWSDP 1.5 is the FCS of the XWS-Security framework. webMethods Glue is not compliant with the latest OASIS specification, and implements a subset of WS-Security signature and encryption algorithms. The results of the interoperability testing suggest that the toolkits lack maturity and may be better-suited to pilot efforts.

    This paper does not address several other issues relevant to Web services security. A compelling reason to use Web services is that endpoints can be loosely-coupled and that the WSDL that describes services can be discovered in a UDDI repository. At this time, however, WS-Security requirements can not be described in WSDL documents.

    IBM, BEA, Microsoft, VeriSign, and others have drafted a family of specifications called WS-Policy that define a framework for indicating a Web service's capabilities, requirements, and characteristics. WS-SecurityPolicy is an addendum to WS-Security, and identifies the WS-Policy assertions that apply to WS-Security. WS-PolicyAttachment defines how to associate policy expressions with WSDL type definitions and UDDI entities. These specifications are still draft releases, however, and have not been submitted to a standards body. Therefore, implementations of WS-Security are available, but no independent standards that describe how to associate security requirements with service descriptions exist.

    Further Reading

    WS-Security Overview
    OASIS Web Services Security (WSS) Technical Committee
    IBM developerWorks: Web services security, Part 1
    IBM developerWorks: Web services security, Part 2
    MSDN Library: Understanding WS-Security

    Apache WSS4J
    Apache WSS4J Project
    Axis Architecture Guide

    Sun Java Web Services Developer Pack
    Java Web Services Developer Pack
    Understanding your JAX-RPC SI environment
    wscompile man page
    MSDN Library: WS-Security Interoperability WSE 2.0 and Sun JWSDP 1.4
    jwsdp: Web Services Interoperability - WS-I

    webMethods Glue
    MSDN Library: WS-Security Interoperability WSE 1.0 and Glue 4.0.1

    Web Services Interoperability Organization (WS-I)
    Deliverables from the Sample Applications Working Group
    Supply Chain Management Sample Architecture

    Trademarks
       webMethods Glue and the webMethods logo are trademarks of webMethods, Inc. "webMethods" is a registered trademark of webMethods, Inc.
       Sun and Sun Microsystems are trademarks or registered trademarks of Sun Microsystems, Inc.
       Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
       Other company, product, and service names mentioned in this document may be trademarks or service marks of others.