Securing Attachments With Metro 1.3

by Ashutosh Shahi

Metro is a high performance, extensible, easy-to-use web services stack. It combines the JAX-WS reference implementation with Project Tango. Project Tango, also called Web Services Interoperability Technology or WSIT, implements numerous WS-\* standards to enable interoperability with other implementations and to provide Quality of Service (QOS) features such as security, reliability, and transaction support. Metro is available in the open source, enterprise-ready GlassFish v2 application server as well as in the modular GlassFish v3 application server. Metro also runs in the Tomcat web container. In addition, it has been successfully used in other application servers.

Metro 1.3 was recently released. With this release, Metro now supports the OASIS specification version of all the major WS-\* specifications that it implements. Earlier Metro releases supported the OASIS submission version of these specifications. As a result, Metro is now interoperable with the Microsoft .NET Framework 3.5, which also supports the same version of the specifications. The earlier releases of Metro were interoperable with the Microsoft .NET Framework 3.0 . Metro is tested for interoperability with .NET releases on a continuous basis and is a primary release criteria. See the Metro Specifications section in the Metro User's Guide for a complete list of the specifications and their versions supported in Metro.

The WS-SecurityPolicy v1.2 specification from OASIS now includes an assertion for integrity and confidentiality protection of SwA (SOAP Messages with Attachments) attachments. This assertion is also a supported feature in Metro 1.3. In this tip, you will learn how to secure an SwA attachment using Metro 1.3 and NetBeans IDE 6.5 (currently available as a Beta release). The new features in the Metro 1.3 release are available in NetBeans IDE 6.5 through a web services plugin.

A sample application package accompanies the tip. The sample application demonstrates a web service and client that securely exchange an SwA attachment using Metro 1.3.

If would want to learn about other aspects of Metro security, see the March 2008 Tech Tip Secure Conversations for Web Services With Metro and the March 2007 Tech Tip Securing Web Services Using WSIT.

An Example of SwA and Security

Securing attachments is described in the WSS:SwA Profile specification. It describes how to use the OASIS Web Services Security: SOAP Message Security specification with SwA. More specifically, the WSS:SwA Profile specification describes how a web service consumer can secure SOAP attachments using SOAP Message Security for attachment integrity, confidentiality, and origin authentication, and how a receiver may process such a message. SwA defines a multi-part MIME structure for packaging attachments with SOAP messages. The structure contains a primary SOAP envelope in its root part and one or more attachments in additional MIME parts. Some of these attachments may have a content type corresponding to XML, but do not contain the primary SOAP envelope to be processed. The WSS:SwA specification considers all attachments as opaque, in other words, arbitrary binary data, whether they are XML or some other content type.

Here is a sample multi-part MIME SOAP message, where the attachment is integrity protected through signing (line numbers have been added for reference):

    1 --uuid:be998ab6-f21a-4ae7-9436-fac806d24efa
    2 Content-Type: text/xml
    4 <?xml version='1.0' encoding='UTF-8'?>"
    5 <S:Envelope xmlns:S=""
    6 xmlns:ds=""
    7  xmlns:exc14n=""
    8  xmlns:wsse=""
    9 xmlns:wsu="">
   10 <S:Header>
   11 .
   12 .
   13 <wsse:Security S:mustUnderstand="1">
   16 <ds:Signature Id="_1">
   17 <ds:SignedInfo>
   18 .
   19 .
   20 <ds:Reference URI="">
   21 <ds:Transforms>
   22 <ds:Transform Algorithm=""/>
   23 </ds:Transforms>
   24 <ds:DigestMethod Algorithm=""/>
   25 <ds:DigestValue>PSrQnx9L+3Vh1ORMk6EWwvY+Mn8=</ds:DigestValue>
   26 </ds:Reference>
   27 .
   28 </ds:SignedInfo>>
   29 <ds:SignatureValue>...</ds:SignatureValue>
   30 .
   31 .
   32 </ds:Signature>
   33 </wsse:Security>
   34 </S:Header>
   35 <S:Body wsu:Id="_5006">
   36 <ns2:uploadFile xmlns:ns2="http://service.techtip/">
   37 <fileName>java.jpg</fileName>
   38 <fileContent></fileContent>
   39 </ns2:uploadFile>
   40 </S:Body>
   41 </S:Envelope>
   42 --uuid:be998ab6-f21a-4ae7-9436-fac806d24efa
   43 Content-Id:<>
   44 Content-Type: image/jpeg
   45 Content-Transfer-Encoding: binary
   46 Binary JPEG Image data
   47 --uuid:be998ab6-f21a-4ae7-9436-fac806d24efa--

When SOAP attachments are used in a SOAP message, the SOAP message is accompanied by a MIME header and possibly multiple boundary parts. This is known as a SOAP message package. The primary SOAP envelope is generally conveyed in the first MIME part. The attachments are carried in other MIME parts and are referenced from the SOAP envelope. In the example message, lines 1 - 41 show the SOAP message, and lines 42 - 47 show the MIME part containing an attachment, in this case a JPEG image. The attachment is referenced from the SOAP body (lines 35 - 40) using a cid:Content-ID reference (line 38). The attachment can also be referenced from the Signature Reference element (line 20), indicating that the signature signs this attachment.

Signing an SwA Attachment

As you can see from the example message, when an SwA attachment is signed, a <ds:Reference> element (line 20) pointing to it is placed inside the <ds:Signature> element (line 16) in the <wsse:Security> header (lines 13-33). The transform element in <ds:Reference> (line 22) specifies if the content only of the MIME package should be signed (Attachment-Content-Signature-Transform) or if both the content and the MIME headers should be signed (Attachment-Complete-Signature-Transform). In Metro 1.3, only the Attachment-Content-Signature-Transform option is supported, and it's enabled by default. This is because the WS-SecurityPolicy 1.2 specification does not provide a way to specify which transform to use for attachments.

Encrypting an SwA Attachment

You can encrypt an SwA attachment for confidentiality protection, and in this way protect the MIME part content (the attachment content) of a SOAP message. You do this using XML encryption elements. You place the resulting cipher text in the updated attachment body, and place an <xenc:EncrptedData> element in the <wsse:Security> header. An <xenc:CipherReference> element must link the <xenc:EncryptedData> element with the cipher data. Here's an example SwA message with an encrypted attachment (line numbers have been added for reference):

    1 --uuid:f4fde266-9bd6-4b8d-a946-a98e4d11f4e5
    2 Content-Type: text/xml
    3 <?xml version='1.0' encoding='UTF-8'?>
    4 <S:Envelope xmlns:S=""
    5   xmlns:ds=""
    6   xmlns:exc14n=""
    7   xmlns:wsse=""
    8   xmlns:wsu=""
    9   xmlns:xenc="">
   10  <S:Header>
   11 .
   12 .
   13 <wsse:Security S:mustUnderstand="1">
   14 .
   15 .
   16 <xenc:EncryptedKey Id="_5007">
   17 <xenc:EncryptionMethod Algorithm=""/>
   18 <ds:KeyInfo xmlns:xsi="" xsi:type="keyInfo">
   19 .
   20 .
   21 </ds:KeyInfo>
   22 <xenc:CipherData>
   23 <xenc:CipherValue>...</xenc:CipherValue>
   24 </xenc:CipherData>
   25 <xenc:ReferenceList>
   26 <xenc:DataReference URI="#_5008"/>
   27 </xenc:ReferenceList>
   28 </xenc:EncryptedKey>
   29 <xenc:EncryptedData Id="_5008" MimeType="image/jpeg" Type="">
   30 <xenc:EncryptionMethod Algorithm=""/>
   31 <xenc:CipherData>
   32 <xenc:CipherReference URI="">
   33 <xenc:Transforms>
   34 <ds:Transform Algorithm=""/>
   35 </xenc:Transforms>
   36 </xenc:CipherReference>
   37 </xenc:CipherData>
   38 </xenc:EncryptedData>
   39 .
   40 .
   41 </wsse:Security>
   42 </S:Header>
   43 <S:Body wsu:Id="_5006">
   44 <ns2:uploadFile xmlns:ns2="http://service.techtip/">
   45 <fileName>java.jpg</fileName>
   46 <fileContent></fileContent>
   47 </ns2:uploadFile>
   48 </S:Body>
   49 </S:Envelope>
   50 --uuid:f4fde266-9bd6-4b8d-a946-a98e4d11f4e5
   51 Content-Id:<>
   52 Content-Type: application/octet-stream
   53 Content-Transfer-Encoding: binary
   54 Encrypted image data Here---
   55 --uuid:f4fde266-9bd6-4b8d-a946-a98e4d11f4e5--

Line 32 shows an <xenc:CipherReference> element inside the <xenc:EncryptedData> element (Line 29). The <xenc:CipherReference> element refers to the attachment Content-ID to be encrypted. The MimeType attribute in the <xenc:EncryptedData> element indicates the Content-Type of the MIME attachment before encryption (in this case, image/jpeg). After encrypting the attachment, the Content-Type is set to application/octet-stream.

Sample Application

The sample application demonstrates a web service and client that securely exchange an SwA attachment using Metro 1.3. The application includes two projects: FileUpload and FileUploadClient. The FileUpload project provides a FileUpload web service that stores binary files on the server. The FileUploadClient project includes a servlet that acts as a client to the FileUpload web service.

The servlet sends a binary file to the FileUpload service in a secured manner, as mandated by the policy of the service. The binary file is sent as an SwA attachment to the service's uploadFile() method. The policy for the web service mandates that the attachment must be integrity and confidentiality protected "on the wire", that is, as the attachment is sent from the client to the service.

Running the Sample

To run the sample, perform the following steps:

  1. Download the sample application and extract its contents. You should now see a newly extracted directory <sample_install_dir>/sample, where <sample_install_dir> is the directory where you installed the sample application. For example, if you extracted the contents to C:\\ on a Windows machine, then your newly created directory should be at C:\\sample.
  2. If you haven't already done so, install NetBeans IDE 6.5 Beta (or a later release), and GlassFish V2UR2. GlassFish V2UR2 is also available in the NetBeans IDE 6.5 Beta download bundle, so you can install the IDE and the application server together.
  3. Download Metro 1.3. Then add it to your GlassFish v2 UR2 installation as follows:
    • Open a command line and enter the command: java -jar metro-1_3.jar. This will create a metro directory and fill it with the Metro 1.3 content.
    • Change to the metro directory by entering the command: cd metro
    • Enter the command: ant -Das.home=<AS_HOME> -f metro-on-glassfish.xml install

      where <AS_HOME> is where you installed GlassFish. It you set AS_HOME as an environment variable, you don't need to specify -Das.home in the command. This command copies the two Metro JAR files into your GlassFish installation's lib directory and makes the necessary classpath alterations in the domain configuration file, domain.xml. It also updates the classpath for the utility script files, wsimport and wsgen.

  4. Configure GlassFish to record message dumps, as follows:
    • Open the file <AS_HOME>/domains/domain1/config/domain.xml in a text editor.
    • Add the following <jvm-options> element:

  5. Start NetBeans IDE 6.5.
  6. Open the FileUpload and FileUploadClient projects. Open each project as follows:
    • Click Open Project in the Projects tab.
    • Navigate to the appropriate project folder. You can find the folders for the two projects in the sample directory of the sample application.Click the Open Project button.
  7. Start the GlassFish application server. You can do this in the NetBeans IDE Services tab by right-clicking GlassFish V2 in the Servers list. Or you can enter the following command:
       <AS_HOME>/bin/asadmin start-domain domain1
  8. Open the FileUpload service as follows:
    • Expand the FileUpload project in the Project tab on the NetBeans IDE.
    • Expand the Web Services node.
    • Right-click the FileUpload service and select Open.
    • Click the Source button above the editor window to display the contents of the file.

    As Figure 1 shows, the class is annotated with a @WebService annotation to identify it as a web service. Notice too that the service has one method, uploadFile(), which is annotated with a @WebMethod annotation that identifies it as a web method. The uploadFile() method uploads files to a server location identified by the UPLOAD_LOC variable. Change the value of UPLOAD_LOC to specify the location on the server where you would like to save the binary files.

    The FileUpload Class

    Figure 1. The FileUpload Class

  9. Set the policy for the service as follows (note that these steps have already been done for the FileUpload project):
    • Expand the Web Services node under the FileUpload project in the Projects view.
    • Right-click the FileUpload service and select Edit Web Service Attributes. This will open a window that displays the Quality of Service attributes for the FileUpload service, as shown in Figure 2.

      Service Policy For <code>FileUpload</code>

      Figure 2. Service Policy For FileUpload

    • Set Version Compatibility to .NET 3.5/Metro 1.3.
    • Check the Secure Service check box and select Mutual Certificates Security from the Security Mechanism drop-down list.
    • Check the Use Development Defaults checkbox. This selects the default keystore and certificates to be used. If you don't check this checkbox, you will need to specify your own certificates.
    • Scroll down to uploadFile operation, and expand the Input Message item.
    • Click the Message Parts button. This opens a Message Parts window that specifies which parts of the message should be secured, as shown in Figure 3.

      Securing Message Parts

      Figure 3. Securing Message Parts

    • Click the Add Attachments button in the Message Parts window to sign and encrypt the SwA attachments. Ensure that the Sign and Encrypt options for the Body and Attachment(s) are checked.
    • Click the OK button in the two open windows to save the configuration.
  10. Right-click the FileUpload Project and select Run. This deploys the service and opens a browser to display the WSDL for the service, as shown in Figure 4.

    The WSDL for the Web Service

    Figure 4. The WSDL for the Web Service

  11. Open the uploadClient class in the FileUploadClient project, as follows:
    • Expand the FileUpload project in the Project tab on the NetBeans IDE.
    • Expand the Source Packages node.
    • Right-click FileUploadClient below the techtip.client source package and select Open.

    As Figure 5 shows, FileUploadClient is a servlet which accesses the FileUpload web service. The code to access the service is in the processRequest() method.

    The <code>FileUploadClient</code> Class

    Figure 5. The FileUploadClient Class

  12. Set the policy for the client (note that these steps have already been done for the FileUploadClient project):
    • Expand the Expand Web Service Reference node in the FileUploadClient project.
    • Right-click the FileUpload service and select Edit Web Service Attributes. This will open a window that displays the Quality of Service attributes for the FileUpload service, as shown in Figure 6.

      Service Policy For <code>FileUpload</code> Service Client

      Figure 6. Service Policy For FileUpload Service Client

    • Check the Use Development Defaults checkbox in under Security. This selects the default certificates to be used.
    • Click the OK button to save the changes.

  13. Right-Click the FileUploadClient project and select Run. This opens a browser window that indicates whether the file upload was successful, as illustrated in Figure 7.

    A Successful File Upload

    Figure 7. A Successful File Upload

    In addition, you should see the attachment, java.jpg, in the target server location, that is, the location that you specified in the UPLOAD_LOC variable within the FileUpload class. Here is the graphic image in the file: The java.jpg graphic
  14. You can view the message flows to ensure that the attachment was secured by examining the log file for the application server located at <AS_HOME>/domains/domain1/logs/server

Further Reading

About the Author

Ashutosh Shahi is a member of the Web Services Security group at Sun Microsystems. He currently works on implementation of WS-\* technologies related to security in the Metro Web Services stack from Sun. Before joining Sun, Ashutosh worked on the development of Apache Axis, an open source SOAP engine from Apache.


How can the client be run if one doesn't use NetBeans?

Posted by Ulf Dittmer on September 29, 2008 at 06:21 PM PDT #


There is a sample available for securing attachments using Metro at . This one is w/o Netbeans.


Posted by Ashutosh Shahi on September 30, 2008 at 12:36 AM PDT #

Hello Ashutosh: I'm having a hard time finding decent documentation on Metro and Tomcat with WS-Security.

Most of what I've found references Glassfish and NetBeans and doesn't work when using Tomcat.

Could you please point me to some good docs on Tomcat, Metro and WS-Security?

Thank you.

Posted by Umk on October 08, 2008 at 06:17 AM PDT #

Umk, perhaps my blog entry here might help you[1].

Ashutosh, do you know why WS-SecurityPolicy covers SwA but not MTOM? I would guess the latter would be the better choice--as it is more modern and supported by Microsoft.


Posted by Glen Mazza on October 13, 2008 at 03:12 PM PDT #

Hello Glen,
There's a policy assertion for MTOM <wsoma:OptimizedMimeSerialization xmlns:wsoma=""/> which XOPs the binary data of size above a specific threshold limit. If that binary data happens to be part of SignedPart or SignedElement (or EncryptedPart and EncryptedElement) e.g <sp:Body/>, it is signed in the SOAP messages. So, the whole process is transparent to the end user. And, thanks for the link.

The steps on tomcat and glassfish should mostly be same except for few steps here and there. Please post queries on Metro forum if you have any issues.


Posted by Ashutosh Shahi on October 14, 2008 at 01:46 PM PDT #

Thank you for the tutorial.
I think we need another one - on how to get SOAP attachments from web services on a client side.

Posted by Alex Zai on October 30, 2008 at 06:39 AM PDT #

Post a Comment:
Comments are closed for this entry.



« January 2017