|
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:
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 OverviewThe 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 TokensThe 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> |
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> |
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.
SignaturesA 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:
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:
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.
Scenario A
|
|
Scenario B
|
|
Scenario C
|
|
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 WSS4JApache 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 ScenariosThe 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 --> |
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"?> |
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 UsernameTokenIf 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:
... |
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> |
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> |
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> |
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 EncryptionThe 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> |
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> |
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 ElementThe 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> |
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 ApplicationA 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:
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 |
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
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.5The 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 ScenariosScenario 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"> |
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 EncryptionThe 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"> |
The schema elements and their meanings are:
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"> |
Most of the schema elements are familiar from discussions of the previous scenarios. The interesting elements and their meanings are:
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:
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) |
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
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.2webMethods 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 ScenariosScenario 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 |
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--> |
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--> |
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 EncryptionThe 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 RequestGlue clients can use templates to declaratively specify their signature and encryption requirements. The client-side scenarioA-client.xml file for this scenario is:
<wsSecurity> |
The interesting <signatureTemplate> schema elements and their meanings are:
The interesting <encryptionTemplate> schema elements and their meanings are:
// set up the WS-Security context |
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--> |
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 ResponseAs 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.
{
|
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 |
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 ElementThe 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> |
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> |
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 ApplicationContact 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:
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 |
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 |
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
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.
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.
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.
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
...
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.
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
...
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.
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 #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.
SummaryThis 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