HomeDigital EditionSys-Con RadioSearch Web Services Cd
B2B Beginning WS Business Process Management Case Studies Content Management Distributing Computing e-Business Electronic Data Interchange Enterprise Industry Insight Integration Interviews Java & Web Services .NET Portal Product Reviews Scalability & Performance Security SOAP Source Code UDDI Wireless WS Standards WS Tips & Techniques WSDL WS Editorials XML

Source Code for this article

Security is not a new concern for companies that want to protect key information and systems from unauthorized access. Protection from such attacks has traditionally been achieved by placing those systems in a tightly controlled intranet accessed through a hardware firewall, possibly over secure TCP/IP connections. However, as more information and functionality are made available over the Web and distributed computing begins to cross corporate Internet boundaries, these mechanisms are no longer adequate. In addition, new concerns arise as a result of distributed computing and transacting business over the Web.

With respect to Web services security, there are five primary areas to consider. Authentication is the act of assuring an entity is who it says it is by providing some form of proof. Authorization is the process of determining what an authenticated user is entitled to do. Confidentiality is a means of guaranteeing that only the intended recipient can view the information being exchanged. Integrity is a means of ensuring that information arrives at its intended destination unaltered. Finally, nonrepudiation is the ability to trace or log the fact that a document was sent and received so that a recipient can't later claim they never received it or that a sender can't deny they sent the document.

It's important to realize that there are many different ways to apply security to a Web services application. This includes leveraging the existing transport and infrastructure capabilities, as well as modification of the SOAP message itself. Each technique has certain advantages and disadvantages. For example, the use of HTTPS for transmitting SOAP messages between client and server provides encryption (confidentiality) of the SOAP message with very little programmatic work required by the developer. However, the disadvantage is the performance degradation encountered in encrypting every message that is exchanged, as well as the lack of flexibility in defining what service is permitted to decrypt the message. In the same way, leveraging infrastructure services for authentication and authorization may mean less work for the programmer but runs the risk of vendor or platform lock-in. On the other hand, applying security to the message itself both provides the greatest flexibility for defining specifically what aspects of security are used and enables a higher degree of interoperability among services operating in a heterogeneous collection of platforms and programming languages.

Security Standards for Web Services
Because Web services is fundamentally built on XML for describing and invoking services, it isn't surprising that XML would also play a large role as the medium for communicating security information. There are a number of XML-based standards that are emerging to address the various aspects of security, such as XML-Signature, XML Encryption, Web Services Security (WSS), and SAML. Some of these standards aren't explicitly limited to Web services in their application, but make sense simply because they are XML-based. No one standard completely addresses all of the issues associated with security, although some will address more than one issue. Table 1 will help you relate some of the standards to the security issues they address.

Table 1

A Web service solution will often combine these technologies to achieve the desired level of security. However, it is important to realize that not all aspects of security will be required for a particular solution. There is almost always a price to pay, whether it is performance, complexity of development and maintenance, or the cost of the solution. As a result, a key guiding principle in applying security is to secure only what must be secured. Think carefully about what aspects of security will be required based on the nature of the service and the environment in which the interaction will take place.

The Strategy
By now, you will have grasped the fact that adding security to Web services can be complex, not only because of the variety of choices available, but also because many of the standards are still evolving. While it's tempting to let this be a barrier to developing Web services or implementing any security, it is important to realize there are strategies that can be used to help reduce complexity and help isolate developers from many of the changes taking place. Here is just one way in which this can be accomplished. Many Web services engines or SOAP servers support the idea of message handlers (sometimes called interceptors). This is the ability to intercept the SOAP message and pass it through a series of processing steps prior to actually delivering the message to the service implementation code. Usually this is an optional step that can be configured and applied to either individual services or to all services deployed on the server.

As an example, suppose that the credit card number element has been encrypted by the sender and a particular service is the intended recipient. An encryption handler could be written to intercept the message, extract the document in the body of the message, decrypt the credit card number, and reinsert the document back into the SOAP body before passing it on to the implementation. There are several benefits to this approach. First, the actual implementation is not encumbered by the task of having to decrypt the element, providing a degree of isolation of tasks. Second, the message handler can be used to wrap potentially unstable APIs or custom functionality in a way that allows later change to the security elements without directly affecting the actual service or client functionality. Figure 1 illustrates the generic handler architecture.

Figure 1

Figure 1 describes in generic terms how the handler mechanism works. Typically, some number of request handlers and response handlers (described in the figure as inbound and outbound handlers) can be registered with the SOAP engine. In addition to defining what handlers will be used, an order of invocation can also be defined. The developer can create a handler for inserting and extracting a specific type of security element, such as XML Encryption or XML-Signatures. Most platforms allow the ability to define and register handlers for the SOAP server. Some platforms, such as Apache Axis, also allow for the ability to define client-side handlers for processing the SOAP request prior to transmitting the request to the service and following receipt of the response from the service.

Now that we've talked about handlers in the generic sense, let's look at a specific example of using client- and server-side handlers to digitally sign and validate a SOAP message with Apache Axis. Consider a situation where a client will be submitting a list of parts for which it wishes a supplier (Acme Supplier) to provide a quote on price and availability. In order for Acme Supplier to be willing to provide a quote, it needs to validate that the request indeed originated from the claimed client. This is done by having the client digitally sign the SOAP message and the Acme Supplier service verify the signature before passing the request on to the actual service implementation. In order to enable this capability, we will create a ClientRequest SigningHandler class to sign the document and a ServerRequest SigningHandler class to intercept the request and validate the signature. Figure 2 shows the Axis-specific architecture for the example we've just outlined.

Figure 2

Apache Axis provides an abstract basic handler (org.apache.axis.BasicHandler) that can be used to get started. In this case it is only required to implement the invoke() method to define the specific behavior you want to provide. In this case, the implementation for the ClientRequest SigningHandler might look something like Listing 1. The details of actually signing the document have been left out here to illustrate just the approach. For a more complete example, please see the entire source code (the source code may be found on the Web at www.sys-con.com/webservices/sourcec.cfm). In order for the client to actually make use of this handler, it must first create and register the handler (see Listing 2).

Finally, Listing 3 is an example implementation of the ServerRequestSigning Handler that will extract and validate the signature before allowing the request to be passed to the implementation.

In order for the Axis server to be aware of and pass the request to the server side request handler, it must be registered as well. This can be done programmatically, but a better way is to include this with the registration of the service itself in the Axis Web Service Deployment Descriptor (WS DD). Listing 4 is an example of the WSDD file that would register the service and a single handler for processing the digital signature.

From this example, you can see that using message handlers is one way to implement security in a Web services architecture with minimal impact to the service and client implementation itself. This approach can be used to isolate the developer from changes that may occur in the security standards and APIs. In addition, it enables a high degree of flexibility in implementing the various aspects of security.

Conclusion
In this article, I've shown an example of using the message handler technique to hide implementation specifics for digitally signing and validating a SOAP message. This technique can also be used to provide XML encryption capabilities, adding WSS elements to a SOAP header, adding SAML assertions and validating them, and so forth. With this technique, it is possible to use multiple handlers to add various security capabilities. For example, one pair of handlers could be used to encrypt and decrypt certain elements of a document while another pair could be used to sign and validate the document.

While many of the security standards are still emerging and stabilizing, it is important to begin thinking about how to secure your Web services. The first step is to be aware of the different aspects of security and the various standards that can be used to secure Web services. The second step is to know the state of these standards so as to not choose technologies that introduce great risk into the solution. The third step is to define a strategy and an architecture for implementing security in a way that provides the greatest amount of isolation from the changes that will most certainly continue to take place throughout this year.

References

  • Hirsch, Frederick. Getting Started with XML Security. (http://home.earthlink.net/~fjhirsch/xml/ xmlsec/starting-xml-security.html)
  • Eastlake, Donald E., III; Niles, Kitty (2002). Secure XML, The New Syntax for Signatures and Encryption (Addison-Wesley).
  • Apache Axis SOAP Toolkit: http://xml.apache.org/axis

    Author Bio
    Mark Secrist is a senior consultant for the HP Developer Resource Organization with more than 10 years of experience involving distributed object technologies and building n-tier, Web-based applications. He currently consults with enterprise customers on J2EE and Web services development. mark_secrist@hp.com

    A Strategy for Securing Web Services by Mark Secrist
    WSJ Vol 03 Issue 3 - pg.9

    	
    
    
    
    Listing 1: ClientRequestSigningHandler
    
    public class ClientRequestSigningHandler extends BasicHandler {
       static {
          // Initialize the xml-security library
          org.apache.xml.security.Init.init();    
       }   
    
       public void invoke(MessageContext msgContext) throws AxisFault {  
          try {
             msgContext.getService();         
             Message requestMessage = msgContext.getRequestMessage();
             SOAPEnvelope unsignedEnvelope = requestMessage.getSOAPEnvelope();
             SOAPEnvelope signedEnvelope = 
                signTheEnvelope(msgContext,unsignedEnvelope);         
             requestMessage = new Message(signedEnvelope); 
             msgContext.setCurrentMessage(requestMessage);         
          } catch (Exception e) { 
              e.printStackTrace();
              throw  AxisFault.makeFault(e);
          }
       }
    }
    
    Listing 2: SupplierServiceClient
    
    String endpointURL = "http://localhost:8080/axis/services/AcmeSupplier";   
    // Set up the call to the service
    Service service = new Service();
    Call call = (Call) service.createCall();
    call.setTargetEndpointAddress(new URL(endpointURL));
    SOAPBodyElement[] reqSOAPBodyElements = new SOAPBodyElement[1];
    // Fill out the SOAP body here
    
    // Create and set the client request handler
    ClientRequestSigningHandler clientReqHandler =
                          new ClientRequestSigningHandler();
    clientReqHandler.setOption("keystore","acmekeystore.jks");
    call.setClientHandlers(clientReqHandler,null);
    // Invoke the service
    Vector resSOAPBodyElements =
                      (Vector) call.invoke(reqSOAPBodyElements);
    
    Listing 3:ServerRequestSigningHandler
    
    public class ServerRequestSigningHandler extends BasicHandler {
       static {
          org.apache.xml.security.Init.init();
       }
    
       public void invoke(MessageContext msgContext) throws AxisFault {
          try {
             Message inMsg = msgContext.getRequestMessage();
             Message outMsg = msgContext.getResponseMessage();
    
             // verify signed message
             Document doc = inMsg.getSOAPEnvelope().getAsDocument();
             CachedXPathAPI xpathAPI = new CachedXPathAPI();
             Element nsctx = doc.createElement("nsctx");
             nsctx.setAttribute("xmlns:ds", Constants.SignatureSpecNS);
    
             Element signatureElem = 
               (Element) xpathAPI.selectSingleNode(doc,"//ds:Signature", nsctx);
    
             XMLSignature sig = 
                 new XMLSignature(signatureElem,"http://acmesupplier.com");
    
             boolean valid =
                 sig.checkSignatureValue(sig.getKeyInfo().getPublicKey());
    
             if (! valid) {
                System.out.println("The signature is invalid");
                throw AxisFault.makeFault(new Exception("Validation Failed"));
             }
             System.out.println("Signature validation succeeded");
          } catch (Exception e) {
             System.out.println("Exception caught: " + e);
             throw AxisFault.makeFault(e);
          }
       }
    }
    
    Listing 4: Axis server deployment file
    
    <deployment
        xmlns="http://xml.apache.org/axis/wsdd/"
        xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
    
      <!-- Define the Signature Handler for the request -->
      <handler name="requestHandler" type="ServerRequestSigningHandler">
        <parameter name="filename" value="MyService.log"/>
      </handler>
    
      <!-- Services from SupplierService WSDL service -->
      <service name="AcmeSupplier" provider="java:RPC" style="document">
          <operation name="getQuote" qname="operNS:QuoteRequest" />
          <parameter name="allowedMethods" value="getQuote"/>
    
          <requestFlow>
             <handler type="requestHandler"/>
          </requestFlow>
       </service>
    </deployment>
    
    

    All Rights Reserved
    Copyright ©  2004 SYS-CON Media, Inc.

      E-mail: info@sys-con.com

    Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.