XWS-Security APIs Sample Application

The focus of api-sample is to demonstrate how to use XWS-Security APIs to secure and validate SOAP messages in a stand-alone (non-JAX-RPC) SAAJ application. The XWS-Security APIs can be used to secure JAX-RPC applications, too, but because securing JAX-RPC applications can be easily accomplished using the security configuration files, this sample application focuses on securing stand-alone, non-JAX-RPC applications.

This sample uses configuration files that start with <xwss:SecurityConfiguration> as the root element, as opposed to the other XWS-Security samples that are based on JAX-RPC and use <xwss:JAXRPCSecurity> as the root element.

Documentation for XWS-Security 2.0 EA APIs is located in the /xws-security/docs/api directory.

The <JWSDP_HOME>/xws-security/samples/api-sample application demonstrates the following functionality:

The application prints out the client request and response SOAP messages. The output from the client is sent to stdout or whichever stream is used by the configured log handler. Messages are logged at the INFO level.

The example code is found in the /api-sample/com/sun/wss/sample/ directory.

The XWSSProcessor Interface

The XWSSProcessor interface defines methods for securing an outbound SOAPMessage and verifying the security in an inbound SOAPMessage. An XWSSProcessor can add and/or verify security in a SOAPMessage in the ways defined by the OASIS WSS 1.0 specification.

The XWSSProcessor interface contains the following methods:

API-Sample Client Code

The client code (samples/api-sample/com/sun/wss/sample/Client.java) uses the XWSSProcessor APIs to secure SOAP messages according to the security policy inferred from the SecurityConfiguration with which this XWSSProcessor was initialized. The following code demonstrates how this is done:

public static void main(String[] args) throws Exception {

        FileInputStream clientConfig = null;
        FileInputStream serverConfig = null;
        try {
            //read client-side security configuration
            clientConfig = new java.io.FileInputStream(
                    new 
java.io.File(System.getProperty("client.configfile")));
            //read server-side security configuration
            serverConfig = new java.io.FileInputStream(
                    new 
java.io.File(System.getProperty("server.configfile")));
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        
        //Create a XWSSProcessFactory.
        XWSSProcessorFactory factory = 
XWSSProcessorFactory.newInstance();
        
        //Create XWSSProcessor to secure outgoing soap messages.
        //Sample SecurityEnvironment is configured to
        //use client-side keystores.
        
        XWSSProcessor cprocessor =
                factory.createForSecurityConfiguration(
                clientConfig, new 
SecurityEnvironmentHandler("client"));
        
        //Create XWSSProcessor to veriy incoming soap messages.
        //Sample SecurityEnvironment is configured to
        //use server-side keystores.
        
        XWSSProcessor sprocessor =
                factory.createForSecurityConfiguration(
                serverConfig, new 
SecurityEnvironmentHandler("server"));
        try{
            clientConfig.close();
            serverConfig.close();
        }catch(Exception ex){
            ex.printStackTrace();
           return;
        }
        
        for(int i=0;i<1;i++){
            
            // create SOAPMessage
            SOAPMessage msg = 
MessageFactory.newInstance().createMessage();
            SOAPBody body = msg.getSOAPBody();
            SOAPBodyElement sbe = body.addBodyElement(
                    SOAPFactory.newInstance().createName(
                    "StockSymbol",
                    "tru",
                    "http://fabrikam123.com/payloads"));
            sbe.addTextNode("QQQ");
            
            //Create processing context and set the soap
            //message to be processed.
            ProcessingContext context = new ProcessingContext();
            context.setSOAPMessage(msg);
            
            //secure the message.
            SOAPMessage secureMsg = cprocessor.secureOutbound-
Message(context);
            
            //verify the secured message.
            context = new ProcessingContext();
            context.setSOAPMessage(secureMsg);

            SOAPMessage verifiedMsg= null;
            try{
                verifiedMsg= sprocessor.verifyInboundMessage(con-
text);
                //System.out.println("\nRequester Subject " + 
SubjectAccessor.getRequesterSubject(context));
                
            }catch(Exception ex){
                ex.printStackTrace();
                //context.getSOAPMessage().writeTo(System.out);
            }
        } 

The API Sample Security Configuration Files

The client (com.sun.wss.sample.Client) code uses the XWSSProcessor APIs to secure SOAP messages according to the security policy inferred from the SecurityConfiguration with which this XWSSProcessor was initialized. The api-sample contains many different example security configuration files. The following pairs should be used when specifying the client and server configuration files in build.properties. The client configuration to specify is listed first, the server configuration second:


Note: The configuration files strid.xml and no_security.xml have syntax errors and should not be used.


Remember, when using the XWS-Security APIs to secure stand-alone application, we will use configuration files that start with <xwss:SecurityConfiguration> as the root element, as opposed to the other XWS-Security samples that are based on JAX-RPC and use <xwss:JAXRPCSecurity> as the root element.

Encrypting the SOAP Message

The security configuration files encryptv1.xml and encryptv2.xml enable the following tasks:

The encryptv1.xml file looks like this:

<xwss:SecurityConfiguration dumpMessages="true" 
   xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">    
   <xwss:Encrypt>
      <xwss:X509Token certificateAlias="s1as"/>
   </xwss:Encrypt>
</xwss:SecurityConfiguration> 

The encryptv2.xml file does the same thing, but specifies the following:

It looks like this:

<xwss:SecurityConfiguration dumpMessages="true"
   xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">    
   <xwss:Encrypt>
        <xwss:X509Token certificateAlias="s1as"/>
        <xwss:KeyEncryptionMethod 
               algorithm="http://www.w3.org/2001/04/xmlenc#rsa-
oaep-mgf1p"/>
        <xwss:DataEncryptionMethod 
               algorithm="http://www.w3.org/2001/04/
xmlenc#aes128-cbc"/>
        <xwss:EncryptionTarget type="xpath" value=".//SOAP-
ENV:Body"/>
   </xwss:Encrypt>
</xwss:SecurityConfiguration> 

Signing the SOAP Message

The security configuration files signv1.xml, signv2.xml, and signv3.xml enable the following tasks:

The signv1.xml file looks like this:

<xwss:SecurityConfiguration dumpMessages="true"  
xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" >
    <!--
      Note that in the <Sign> operation, a Timestamp is exported
      in the security header and signed by default.
    -->
    <xwss:Sign>
        <xwss:X509Token certificateAlias="xws-security-client"/>
    </xwss:Sign>
</xwss:SecurityConfiguration> 

The signv2.xml file does the same thing, except that it also includes the following:

It looks like this:

<xwss:SecurityConfiguration dumpMessages="true" 
xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" >
    <xwss:Sign>
        <xwss:X509Token certificateAlias="xws-security-client"/>
     <xwss:CanonicalizationMethod algorithm=
        "http://www.w3.org/2001/10/xml-exc-c14n#"/>
        <xwss:SignatureMethod
              algorithm="http://www.w3.org/2000/09/
xmldsig#rsa-sha1"/>
             <xwss:SignatureTarget type="uri" value="">
                  <xwss:DigestMethod 
                       algorithm="http://www.w3.org/2000/09/
xmldsig#sha1"/>
                  <xwss:Transform 
                  algorithm="http://www.w3.org/TR/1999/REC-
xpath-19991116">
                         <xwss:AlgorithmParameter name="XPATH" 
                         value="./SOAP-ENV:Envelope/SOAP-
ENV:Header/wsse:Security/
                        ds:Signature[1]/ds:KeyInfo/
wsse:SecurityTokenReference"/>
                  </xwss:Transform>
                  <xwss:Transform algorithm="http://
docs.oasis-open.org/wss/2004/01/
                  oasis-200401-wss-soap-message-security-
1.0#STR-Transform">
                        <xwss:AlgorithmParameter 
name="CanonicalizationMethod" 
                        value="http://www.w3.org/2001/10/xml-
exc-c14n#"/>
                  </xwss:Transform>
             </xwss:SignatureTarget>
    </xwss:Sign>
</xwss:SecurityConfiguration> 

The signv3.xml file looks the same as signv1.xml file, except that it sends the subject key identifier extension value of the certificate, instead of the actual certificate, along with the message. It looks like this:

<xwss:SecurityConfiguration dumpMessages="true"  
xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" >
    <!--
      Note that in the <Sign> operation, a Timestamp is exported
      in the security header and signed by default.
    -->
    <xwss:Sign>
        <xwss:X509Token certificateAlias="xws-security-client" 
              keyReferenceType="Identifier"/>
    </xwss:Sign>
</xwss:SecurityConfiguration> 

The sign-rsign.xml file looks like the signv1.xml file, except that it requires a signature. It looks like this:

<xwss:SecurityConfiguration dumpMessages="true"  
xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" >
    <xwss:Sign>
        <xwss:X509Token certificateAlias="xws-security-client"/>
    </xwss:Sign>
    <xwss:RequireSignature/>
</xwss:SecurityConfiguration> 

The str-transform.xml file uses a Security Token Reference (STR) Dereference Transform, which is an option for referencing information to be signed. Other methods for referencing information to be signed include referencing URIs, IDs and XPaths. Use an STR-Transform when a token format does not allow tokens to be referenced using URIs or IDs and an XPath is undesirable. STR-Transform allows you to create your own unique reference mechanism. It looks like this:

<xwss:SecurityConfiguration dumpMessages="true" 
xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" >
      <xwss:Sign>
            <xwss:X509Token certificateAlias="xws-security-
client"/>
      </xwss:Sign>
      <xwss:Sign>
            <xwss:X509Token certificateAlias="xws-security-
client"/>
            <xwss:Target 
                  type="qname">{http://schemas.xmlsoap.org/
soap/envelope/}Body
                  </xwss:Target>
            <xwss:SignatureTarget type="xpath" 
            value="/SOAP-ENV:Envelope/SOAP-ENV:Header/
wsse:Security/ds:Signature[1]/
            ds:KeyInfo/wsse:SecurityTokenReference">
                        <xwss:DigestMethod 
                        algorithm="http://www.w3.org/2000/09/
xmldsig#sha1"/>
                        <xwss:Transform algorithm="http://
docs.oasis-open.org/wss/2004/01/
                        oasis-200401-wss-soap-message-secu-
rity-1.0#STR-Transform">
                              <xwss:AlgorithmParameter 
name="CanonicalizationMethod"
                              value="http://www.w3.org/2001/
10/xml-exc-c14n#"/>
                  </xwss:Transform>
            </xwss:SignatureTarget>
      </xwss:Sign>
</xwss:SecurityConfiguration> 

Sending a Username Token with the SOAP Message

The security configuration username.xml enables the following tasks:

The username.xml file looks like this:

<xwss:SecurityConfiguration dumpMessages="true" 
xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
            <xwss:UsernameToken name="Ron" password="noR"/>
            <xwss:RequireUsernameToken/>
</xwss:SecurityConfiguration> 

Building and Running the API Sample Application

This sample does not require that a container be running, so there is no need to start the Application Server for this example.

To run the api-sample application, follow these steps:

  1. Complete the tasks defined in the following sections of this addendum:
  2. Modify the client.configfile and server.configfile properties in the build.properties file so that they points to a valid security configuration pair you want to run.
  3. Build and run the application from a terminal window or command prompt.
    • On the Application Server, the command to build and run the application is: asant run-sample
    • On the other containers, the command to build and run the application is: ant run-sample

Note: To run the sample against a remote server containing the deployed endpoint, use the run-remote-sample target in place of the run-sample target. In this situation, make sure that the endpoint.host, endpoint.port, http.proxyHost, http.proxyPort, and service.url properties are set correctly in the build.properties file (as discussed in Setting Build Properties) before running the sample.