Building XPath expressions for WS-Security
JAX-RPC and JAX-WS WS-Security configurations use XML-based SOAP messages to exchange information between applications. We can use an XPath expression to select specific elements in a SOAP message to sign or encrypt.
To sign or encrypt elements in a Simple Object Access Protocol (SOAP) message, we can use XPath expressions to select the specific elements in the message. SOAP 1.1 and SOAP 1.2 messages differ in format and therefore require separate XPath expressions to select elements from each version of the message. The JAX-WS runtime environment supports both SOAP 1.1 and SOAP 1.2., so we must add two XPath expressions to the WS-Security policies for each element to select: one for SOAP 1.1, and one for SOAP 1.2. The JAX-RPC runtime environment supports only SOAP 1.1, so we must add only the SOAP 1.1 version of the XPath expression to the WS-Security policies.
The differences in the format of SOAP 1.1 and SOAP 1.2 messages are highlighted in the following scenario of selecting the Timestamp element from SOAP messages in a JAX-WS WS-Security configuration.
SOAP 1.1 message with a Timestamp element.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsu:Timestamp wsu:Id="Timestamp-16" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <wsu:Created>2012-01-11T12:55:41.781Z</wsu:Created> <wsu:Expires>2012-01-11T15:42:21.781Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soapenv:Header> </soapenv:Envelope>SOAP 1.2 message with a Timestamp element.
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsu:Timestamp u:Id="uuid-169b0950-217e-48af-9057-ea832e0c7e19-14" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <wsu:Created>2009-09-08T14:08:36.224Z</wsu:Created> <wsu:Expires>2009-09-08T14:13:36.224Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soapenv:Header> </soapenv:Envelope>The XPath expressions that select SOAP message elements are in the WS-Security default policies that contain configuration information for XML Digital Signature. In a JAX-WS WS-Security configuration, the XPath expressions appear in pairs, with one XPath expression for each supported version of SOAP.
The following example shows the XPath expressions that select the Timestamp element from the SOAP 1.1 and SOAP 1.2 messages in the previous examples. The first XPath expression selects Timestamp from the SOAP 1.1 message, and the second XPath expression selects Timestamp from the SOAP 1.2 message.
/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/' and local-name()='Envelope'] /*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/' and local-name()='Header'] /*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' and local-name()='Security'] /*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd' and local-name()='Timestamp'] /*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope' and local-name()='Envelope'] /*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope' and local-name()='Header'] /*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' and local-name()='Security'] /*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd' and local-name()='Timestamp']The first two lines of the XPath expressions for each version are different, and the last two lines of the XPath expressions are the same. The difference between the two XPath expressions is the namespace in the Envelope and Header elements. The namespaces in the XPath expressions correspond to the namespaces in the SOAP 1.1 and SOAP 1.2 messages.
This task describes how to build XPath expressions used to select an element to sign or encrypt in WS-Security. JAX-WS security configurations require separate XPath expressions for both SOAP 1.1 and SOAP 1.2, while JAX-RPC security configurations require XPath expressions only for SOAP 1.1.
To select a SOAP message element that is commonly used in WS-Security, see option 1 to build XPath expressions using pre-built code segments. Otherwise, proceed to option 2 to learn how to build custom XPath expressions for other elements.
The XPath expression examples in this task are shown across multiple lines for formatting and clarity. When adding your completed XPath expressions into WS-Security, we must enter the complete XPath expression as a single line.
Tasks
- Build a common XPath expression using pre-built code segments.
- Build the part of the XPath expression that points to the SOAP Security header.
- SOAP 1.1:
/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/' and local-name()='Envelope'] /*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/' and local-name()='Header'] /*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' and local-name()='Security']- SOAP 1.2:
/*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope' and local-name()='Envelope'] /*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope' and local-name()='Header'] /*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' and local-name()='Security']
- Add the part of the XPath expression that corresponds to the element to sign or encrypt. The XPath expression lines for commonly used elements are shown in the following list.
- UsernameToken
/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' and local-name()='UsernameToken']- BinarySecurityToken (LTPA, X.509, Kerberos, and so on.)
/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' and local-name()='BinarySecurityToken']- SAML 1.1 Assertion (encryption only)
/*[namespace-uri()='urn:oasis:names:tc:SAML:1.0:assertion' and local-name()='Assertion']- SAML 2.0 Assertion (encryption only)
/*[namespace-uri()='urn:oasis:names:tc:SAML:2.0:assertion' and local-name()='Assertion']- SecurityTokenReference in the Security header (for STR-Transform)
/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' and local-name()='SecurityTokenReference']- SecurityTokenReference within a Signature element
/*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#' and local-name()='Signature'] /*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#' and local-name()='KeyInfo'] /*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' and local-name()='SecurityTokenReference']- Timestamp
/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd' and local-name()='Timestamp']- Signature (encryption only)
/*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#' and local-name()='Signature']
- Build a custom XPath expression.
- Locate the element we want to select within the structure of the SOAP message.
For example, the following SOAP message contains the element CreditCardNumber.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <ns1:myToken xmlns:ns1="http://token/space" value="tokenValue"/> </wsse:Security> </soapenv:Header> <soapenv:Body> <ns2:CreditCardNumber xmlns:ns2="http://bank/space" value="1234"/> </soapenv:Body> </soapenv:Envelope>To select CreditCardNumber, isolate only the elements of the SOAP message that surround it. The following example shows the structure of the SOAP message that is relevant to selecting CreditCardNumber.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <ns2:CreditCardNumber xmlns:ns2="http://bank/space" value="1234"/> </soapenv:Body> </soapenv:Envelope>- Write one XPath segment for each element in the SOAP message structure containing the target element. Each XPath segment must include the namespace and local name of its corresponding element put into the following format:
/*[namespace-uri()='http://namespace/url' and local-name()='ElementName']For example, the following XPath segment corresponds to the Envelope element from the example in the previous step.
/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/' and local-name()='Envelope']If the element does not contain a namespace, it inherits the namespace of the element containing it. For example, the Body element uses the namespace from the Envelope element.
- Combine the XPath segments into one complete expression. The segments should be ordered from the outermost element to the innermost element, which is the element that we are selecting.
The following example shows the complete XPath expression that selects the CreditCardNumber element from the example in the first step.
/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/' and local-name()='Envelope'] /*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/' and local-name()='Body'] /*[namespace-uri()='http://bank/space' and local-name()='CreditCardNumber']
You built an XPath expression that selects an element of a SOAP 1.1 or SOAP 1.2 message header.
Example
Complete SOAP 1.2 XPath expression that selects a UsernameToken.
/*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope' and local-name()='Envelope'] /*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope' and local-name()='Header'] /*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' and local-name()='Security'] /*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' and local-name()='UsernameToken']
What to do next
Enter the complete XPath expression into the WS-Security policy configuration as a single line of text.