Secure XML: The New Syntax for Signatures and Encryption
The fundamental communicating entities from SOAP's point of view are "nodes," as shown in Figure 8-1. A SOAP message start at the original sender node, proceeds through zero or more intermediate nodes, and terminates at the ultimate receiver node. A message always has a top-level element, "Envelope," in the soap-envelope namespace. Figure 8-1. Message transmission modelAlthough SOAP does not provide message routing, it fundamentally recognizes that messages can pass through intermediate nodes on the way to their destinations. This protocol does not have a traditional versioning label. If a SOAP node receives a message with an unrecognized top-level element (anything other than Envelope) or namespace, however, it must generate a SOAP VersionMismatch Fault (see Section 8.2.4). 8.2.1 SOAP Messages
SOAP messages contain an optional Header element and a mandatory Body element. Each of these items can contain Blocks, as shown in Figure 8-2. The SOAP Header extends SOAP messages. For example, a Header Block could be used for authentication as described in Chapter 11. Figure 8-2. SOAP message structureExample 8-1 shows a simple SOAP message consisting of a Header and a Body, with each containing one Block. Example 8-1 Simple SOAP message
<env:Envelope xmlns:env="http://www.w3.org/2001/12/soap-envelope"> <env:Header> <foo:control xmlns:foo='http://www.example.net/protocol'> <foo:example attribute="value"/> </foo:control> </env:Header> <env:Body> <foo:data xmlns:foo='http://www.example.net/protocol'> ...y8gaGp5WVtMODq7b29bGxjI4OIBH... </foo:data> </env:Body> </env:Envelope> SOAP has quite liberal rules regarding what you can include as an attribute at the Envelope or Header/Body level. The meaning of such attributes, beyond those actually defined by SOAP, is unclear. It is best to extend SOAP through Block elements or attributes at the Block level or below rather than through such high-level element attributes. 8.2.2 SOAP Actors
As noted earlier, a SOAP message has two parts, the Header and the Body, each of which consists of SOAP Blocks. Every SOAP Header Block can have an optional "actor" attribute in the soap-envelope namespace with a URI value. This attribute indicates that the target for that Block is a node that fulfills the role of that actor. Header Blocks with no "actor" attribute and all Body Blocks are targeted to the ultimate receiver node. (SOAP Body Blocks cannot have an "actor" attribute.) Nodes take on the role of "actors," where a URI identifies each actor. A SOAP node can fulfill the role of many actors. Every SOAP node must act in the role of the special SOAP actor: http://www.w3.org/2001/12/soap-envelope/actor/next No SOAP node may act in the role of the special SOAP actor: http://www.w3.org/2001/12/soap-envelope/actor/none Header Blocks for the "none" actor consequently have the following characteristics:
A SOAP node that fulfills the role of the "anonymous" actor is an ultimate receiver. It may seem natural for actor names to be related to the host name of the node where the actors run and to be useful in routing messages. In reality, SOAP imposes no such restrictions and does not provide any routing. (Note: A transport to which SOAP is bound would normally provide routing, as discussed in Section 8.4.) A particular SOAP Block is understood at a particular SOAP node if the node implements and conforms to the semantics of that Block. The namespace-qualified apex element name in that Block indicates which semantics are in use. A requirement that a Block be understood can be imposed through the "mustUnderstand" attribute in the soap-envelope namespace. If that attribute is present at a block with the value "true," then a SOAP node fulfilling the role of the actor specified by the Block (or the ultimate destination if the Block specifies no actor):
Example 8-2 shows a SOAP message with two Header Blocks and one Body Block. Each Header Block has an "actor" attribute, and one such Block has a mustUnderstand attribute value of "true." Example 8-2 A SOAP message with actors
<env:Envelope xmlns:env="http://www.w3.org/2001/12/soap-envelope"> <env:Header> <foo:control xmlns:foo='http://www.example.net/protocol' env:actor='http://example.net/protocol/control'> <foo:example attribute="value"/> </foo:control> <bar:priority xmlns:bar='http://www.example.net/protocol' env:actor='http://priority.test' env:mustUnderstand='true'> <bar:level>high</foo:level> </bar:priority> </env:Header> <env:Body> <foo:data xmlns:foo='http://www.example.net/protocol'> y8gaGp5WVtMODq7b29bGxjI4OIBH... </foo:data> </env:Body> </env:Envelope> Although the standard defines the SOAP Header and Body as separate elements, they are, in fact, related. There is no difference between a Block appearing in the Body, where it cannot have an "actor" or "mustUnderstand" attribute, and the same Block appearing in the Header with no "actor" attribute and a "mustUnderstand" attribute value of "true." A Block with no actor attribute is targeted at the actor identified with a null URI that is, the anonymous actor. The presence of such an actor indicates an ultimate receiver SOAP node. 8.2.3 SOAP Processing
The processing at a SOAP node must be equivalent to the following steps:
Failure while processing a SOAP message at a node produces exactly one Fault. 8.2.4 SOAP Faults
SOAP nodes return error or status information to a node from which they have received a message. They send back a SOAP message with a Body Block consisting of the Fault element in the soap-envelope namespace. Fault has two mandatory child elements, "faultcode" and "faultstring," and two optional child elements, "faultactor" and "detail."
Table 8-1 lists the values of "faultcode" defined by the SOAP specification. All of these values appear in the soap-envelope namespace. For the "Sender" and "Receiver" values, more information may be present in the Fault "detail" child element. An example "faultcode" might be <faultcode xmlns:foo="http://example.com">foo:problem</faultcode>
VersionMismatch Faults
The SOAP version really refers to the SOAP Envelope version. More common than an envelope version change is requiring a particular extension by a Header Block with a mustUnderstand attribute of "true" for that extension. If the server does not support the extension, the SOAP node must return a "MustUnderstand" Fault. In the much less common case of change in the envelope structure, a SOAP node may support multiple envelope structure versions. If it receives a message with a root element it does not understand, its "VersionMismatch" Fault response should include a Header Block consisting of an "Upgrade" element in the following namespace: http://www.w3.org/2001/12/soap-upgrade The content of the "Upgrade" element is an ordered list of the envelope versions supported by the server, starting with the most preferred and ending with the least preferred. The lack of an "Upgrade" element may indicate that the server supports only SOAP version 1.1. MustUnderstand Faults
When a SOAP node returns a "MustUnderstand" Fault, the message should include Header Blocks that indicate which Blocks were not understood. These Header Blocks consist of the "Misunderstood" element in the http://www.w3.org/2001/12/soap-faults namespace. This Misunderstood element has a "qname" attribute, whose value is the namespace-qualified name of the element that was not understood. A namespace declaration in the Misunderstood element or an ancestor thereof must also bind the namespace prefix used by the qualified name. See Example 8-3. Example 8-3 Misunderstood fault
Original Message: <env:Envelope xmlns:env="http://www.w3.org/2001/12/soap-envelope"> <env:Header> <foo:extension xmlns:foo='http://www.example.illegal/protocol' env:mustUnderstand='1'/> </env:Header> <env:Body>...</env:Body> </env:Envelope> Resulting "Misunderstood" Fault: <env:Envelope xmlns:env="http://www.w3.org/2001/12/soap-envelope"> <env:Header> <f:Misunderstood xmlns:f="http://www.w3.org/2001/12/soap-faults" f:qname='foo:extension xmlns:foo='http://www.example.illegal/protocol'/> </env:Header> <env:Body> <env:Fault> <faultcode>env:mustUnderstand</faultcode> <faultstring>Never heard of "foo"</faultstring> </env:Fault> </env:Body> </env:Envelope> 8.2.5 SOAP Envelope and Fault Schemas
Below is the schema for the SOAP Envelope element and for its Header and Body children from <http://www.w3.org/2001/12/soap-envelope> adapted for shorter lines. The version of a SOAP Envelope is indicated by its namespace. If a node receives a SOAP message with an Envelope element namespace it does not understand, it responds with a VersionMismatch Fault. The following also includes a schema for Fault. <!-- Schema defined in the SOAP Version 1.2 Part 1 specification 17 December 2001 Working Draft: http://www.w3.org/TR/2001/WD-soap12-part1-20011217/ $Id: soap-envelope.xsd,v 1.1 2001/12/14 13:35:22 ylafon Exp $ Copyright 2001 W3C (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/ This document is governed by the W3C Software License [1] As described in the FAQ [2]. [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720 [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD --> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.w3.org/2001/12/soap-envelope" targetNamespace="http://www.w3.org/2001/12/soap-envelope" > <!-- Envelope, header and body --> <xs:element name="Envelope" type="tns:Envelope" /> <xs:complexType name="Envelope" > <xs:sequence> <xs:element ref="tns:Header" minOccurs="0" /> <xs:element ref="tns:Body" minOccurs="1" /> </xs:sequence> <xs:anyAttribute namespace="##other" processContents="lax" /> </xs:complexType> <xs:element name="Header" type="tns:Header" /> <xs:complexType name="Header" > <xs:sequence> <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" /> </xs:sequence> <xs:anyAttribute namespace="##other" processContents="lax" /> </xs:complexType> <xs:element name="Body" type="tns:Body" /> <xs:complexType name="Body" > <xs:sequence> <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" /> </xs:sequence> <xs:anyAttribute namespace="##any" processContents="lax" > <xs:annotation> <xs:documentation> Prose in the spec does not specify that attributes are allowed on the Body element </xs:documentation> </xs:annotation> </xs:anyAttribute> </xs:complexType> <!-- Global Attributes. The following attributes are intended to be usable via qualified attribute names on any complex type referencing them. --> <xs:attribute name="mustUnderstand" type="xs:boolean" default="0" /> <xs:attribute name="actor" type="xs:anyURI" /> <xs:simpleType name="encodingStyle" > <xs:annotation> <xs:documentation> 'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element. For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification </xs:documentation> </xs:annotation> <xs:list itemType="xs:anyURI" /> </xs:simpleType> <xs:attributeGroup name="encodingStyle" > <xs:attribute name="encodingStyle" type="tns:encodingStyle" /> </xs:attributeGroup> <xs:element name="Fault" type="tns:Fault" /> <xs:complexType name="Fault" final="extension" > <xs:annotation> <xs:documentation> Fault reporting structure </xs:documentation> </xs:annotation> <xs:sequence> <xs:element name="faultcode" type="xs:QName" /> <xs:element name="faultstring" type="xs:string" /> <xs:element name="faultactor" type="xs:anyURI" minOccurs="0" /> <xs:element name="detail" type="tns:detail" minOccurs="0" /> </xs:sequence> </xs:complexType> <xs:complexType name="detail"> <xs:sequence> <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" /> </xs:sequence> <xs:anyAttribute namespace="##any" processContents="lax" /> </xs:complexType> </xs:schema> |