GXA Specifications in WSE


As you saw in Table 12-1, 11 specifications currently fall under the GXA banner. We’ll first look at the five that are implemented in the Web Service Enhancements (WSE) package and in the next three chapters we’ll go into these in a lot more detail.

We’ll provide enough detail that when we look at the WSE implementation of these specifications, you can appreciate what is going on and will have a basic understanding of the various XML constructs that are passed to and from Web services.

We’ll look at the remaining six specifications later in the chapter.

WS-Attachments

The WS-Attachments specification is different from the other specifications in that there is no WS-Attachments specification document as such. Instead, the WS-Attachments specification is a GXA name for the IETF-defined Direct Internet Message Encapsulation (DIME) specification.

Note

The DIME specification was an IETF Internet draft that never made it to RFC status. WS-Attachments is based on the last released version of the DIME specification and can be found at http://msdn.microsoft.com/library/en-us/dnglobspec/html/draft-nielsen-dime- soap-01.txt. When you use DIME for the WS-Attachments specification, no changes are made to the way DIME messages are constructed and transmitted. The only stipulation for WS-Attachments is that the SOAP envelope of the message be encapsulated in the first DIME record in the DIME message, with any attachments added as subsequent DIME records.

The DIME specification is a method of encapsulating data (a payload, in DIME parlance) in any format in a binary message that follows a specified structure.

A DIME message basically consists of a series of DIME records or DIME record chunks. A DIME record has a maximum size of 2^32-1 bytes and if the payload is bigger than what can be accommodated in a single DIME record, it will be split across several DIME record chunks.

All of the work to construct and deconstruct DIME messages is handled by the framework you use, but it is worthwhile to understand how a DIME message and the DIME records and DIME record chunks that it contains are constructed.

DIME Messages

As we said earlier, the DIME message consists of a series of DIME records or DIME record chunks, which we’ll look at shortly. What we’re interested in here is the organization of these records and record chunks into the overall message.

A DIME message is, fundamentally, a single binary stream with the details of what is encoded being left to the record and record chunk constructs. When you transmit a DIME message, you set the media type of the message to application/dime and hope that the receiver understands this media type and knows how to decode the DIME message you’ve sent.

Within the message, you simply place the records and record chunks in the order you want them to be received, and you specify the first object and the final object in the message—you don’t use object numbering because the order of the objects in the message is determined by their position. A schematic look at a DIME message is shown in Figure 12-1.


Figure 12-1: A simple DIME message

As you can see, the message has four DIME records (R1 to R4). We also set two of the DIME record flags to indicate the start and end of the message, respectively. We use the MB flag to specify the first record in the message, and we use the ME flag to specify the final record in the message.

DIME Records

The overall structure of a DIME record is shown in Figure 12-2.

click to expand
Figure 12-2: The DIME record structure

As you can see, a DIME record is quite compact and has only four bits (the RESERVED field) that aren’t actually used. Each of the fields performs a different function:

  • VERSION Specifies the version of the DIME record format you’re using. This is an unsigned 5-bit integer; at present, only the value 1 is defined.

  • MB If set, this single bit specifies that this DIME record is the first record in the message.

  • ME If set, this single bit specifies that this DIME record is the final record in the message.

  • CF A single bit that is set when a payload is split across several DIME record chunks.

  • TYPE_T A 4-bit integer that is used to specify what the TYPE field will contain. The two values you’ll use most often are media-type (1) and absoluteURI (2). You use media-type when the record contains a payload that has a MIME type, and you use the absoluteURI value when you’re dealing with a type that is specified by a URI (such as a SOAP envelope).

  • RESERVED A 4-bit field that is reserved for future use and must be set to 0.

  • OPTIONS_LENGTH, ID_LENGTH and TYPE_LENGTH Unsigned 16-bit integers that specify the length of the OPTIONS, ID, and TYPE fields, respectively (minus any padding that is required). If any of these values are set to 0, the field whose length they specify will not be present in the record.

  • DATA_LENGTH A 32-bit unsigned field that specifies the length of the DATA field.

  • OPTIONS A variable-length field, padded to the next 16 bits, that contains various optional properties for the DIME record. In the current release of the DIME specification, this field doesn’t contain any meaningful information.

  • ID A variable-length field, padded to the next 16 bits, that contains a unique ID for the record. In most cases, this will not actually be present in the record and the ID_LENGTH field will be set to 0.

  • TYPE A variable-length field, padded to the next 16 bits, that contains the type of the record. This flag must be valid for the type system specified by the TYPE_T flag.

  • DATA A variable-length field, padded to the next 16 bits, that contains the actual data for the record.

DIME Record Chunks

As we implied earlier, a DIME record chunk is simply a DIME record with several of the flags that specify the DIME record set slightly differently. For a DIME record chunk, the following fields are set:

  • CF You set this flag to 1 to indicate that the record is actually a record chunk.

  • TYPE_T, TYPE_LENGTH, and TYPE For the first record chunk, you set these values as you do for a normal DIME record, but for all following chunks the TYPE_T value must be set to unchanged (0) and the TYPE_LENGTH flag must be set to 0. We have a zero-length type field, so we can’t specify the TYPE field.

You place the data in the DATA field as you do for normal DIME records, and the data can be split arbitrarily by the sender. The recipient is responsible for interpreting the flags set for the record and combining all of the record chunks, in the correct order, to retrieve the original data.

WS-Security

The WS-Security specification was one of the first specifications released under the GXA banner and is the one that has been most emphasized since it was released.

Note

The first draft of the WS-Security specification was released on April 5, 2002, and was amended by the WS-Security Addendum on August 18, 2002. This addendum tidied up a few inconsistencies in the original specification and can be considered the base implementation of WS-Security. The specification is in the http://schemas.xmlsoap.org/2002/07/secext namespace and is usually given the wsse prefix.

You can achieve a measure of security by using a transport protocol that has built- in security (such as HTTPS, which uses SSL to provide an encrypted channel between the client and the server), but the WS-Security specification provides security across any transport protocol you want to use.

The WS-Security specification provides security to the messages transmitted between clients and Web services by using message authentication, integrity, and confidentiality.

Although WS-Security provides a framework for adding security details to messages and for securing those messages, the actual details of how to ensure the integrity and confidentiality of messages is contained in two W3C recommendations that we’ll look at shortly. The basic WS-Security specification is also the basis for a whole raft of additional specifications that we’ll look at when we discuss the specifications released after the WS-Security specification.

Security Tokens

The entire WS-Security implementation is based on the use of security tokens. A security token is a structure that encapsulates the security credentials of a message transmitter.

The WS-Security specification defines two types of security token—a signed security token that has been endorsed by a specific authority (such as X509 certificates and Kerberos tickets) and an unsigned security token that has not been endorsed by a third party.

The unsigned security token defined in the WS-Security specification is <wsse:UsernameToken>; you can use this token to pass username and password details for authentication.

The signed security token, <wsse:BinarySecurityToken>, is used to encapsulate any binary security tokens (such as X509 certificates and Kerberos tickets) or any security token that is in a non-XML format.

<wsse:UsernameToken> element

The <wsse:UsernameToken> element is unsigned and allows you to pass a username and password combination with the message, which can then be read by the recipient of the message and used to authenticate the sender. The structure of <wsse:UsernameToken> is as follows:

<wsse:UsernameToken  xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"  wsu:>   <wsse:Username>...</wsse:Username>   <wsse:Password Type="...">...</wsse:Password>   <wsse:Nonce EncodingType="...">...</wsse:Nonce>   <wsu:Created>...</wsu:Created> </wsse:UsernameToken>

The <wsse:Username> and <wsse:Password> elements allow you to specify the username and password. Sending a plaintext password is not particularly secure, but using the Type attribute of the <wsse:Password> element, you can specify that the password is actually a digest value encoded using the SHA1 hash algorithm.

Using a digest value for the password is still not secure because the relationship between the password and the digest value of the password is well known. For this reason, the <wsse:Nonce> and <wsu:Created> elements were added in the WS-Security Addendum. You can use these elements to provide additional security to the password by providing a digest password that is a combination of the real password as well as the values of the <wsse:Nonce> and <wsu:Created> elements.

The extra features defined in the WS-Security Addendum do solve several security problems, but the relationship between the password digest and the real password is still well known. We can calculate the real password relatively easily knowing the different elements in the <wsse:UsernameToken> element.

If you’re using a secure channel, however, and the security used by the channel meets your requirements, you can use <wsse:UsernameToken> security to authenticate the user. But if you need to send messages across a nonsecure channel, you have to use a more secure mechanism such as X509 certificates or Kerberos tickets.

<wsse:BinarySecurityToken> element

The <wsse:BinarySecurityToken> element is used to pass security tokens that are binary in nature or are non-XML. The current release of the specification defines three types of binary security token—X509 certificates and two types of Kerberos ticket—but the current implementation of WSE allows you to use only X509 certificates. We’ll therefore concentrate our discussion on X509 certificates.

A typical <wsse:BinarySecurityToken> is defined as follows:

<wsse:BinarySecurityToken ValueType="..." EncodingType="..."  xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"  wsu:>   ... </wsse:BinarySecurityToken>

As you can see, the <wsse:BinarySecurityToken> has three attributes and these allow us to specify what the security token is. We define the type of the security token in the ValueType attribute and specify how it is encoded in the EncodingType attribute. Then wsu:Id attribute is used to provide a unique identifier that is used when we sign and encrypt the messages we’re sending.

The content of the <wsse:BinarySecurityToken> element is the textual representation of the security token. Using the type and encoding specified by the ValueType and EncodingType attributes, the recipient of the message can reconstruct the security token.

Authentication

As you’ve seen, the WS-Security specification allows you to authenticate the message that is received. Unfortunately, this process is susceptible to all of the security problems that are prevalent on the Internet. Without proper security provided by the transport protocol, the information you enter is easy to steal. If you’re not using a secure transport protocol, message authentication on its own will not provide any security and you’ll need to look at the sections titled “Integrity Through Signing” and “Confidentiality Through Encryption.”

When you authenticate a message, you simply add the security token to the message in the <wsse:Security> SOAP header, as follows:

<soap:Header>   <wsse:Security soap:mustUnderstand="1"    xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext">     <wsse:UsernameToken      xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"      wsu:>       <wsse:Username>test1</wsse:Username>        <wsse:Password Type="wsse:PasswordText">pass1</wsse:Password>        <wsse:Nonce>EgWWZYqwaf5Dr5+5ZkZp9A==</wsse:Nonce>        <wsu:Created>2003-04-14T19:32:32Z</wsu:Created>      </wsse:UsernameToken>   </wsse:Security> </soap:Header>

Although we added a username and password combination using the <wsse:UsernameToken> element, you can also use <wsse:BinarySecurityToken> for authentication. However, if you’re using X509 certificates, there isn’t much point because you have to pass the public part of the certificate, and this is freely available.

If you’re using a secure transport protocol, using a username and password combination to authenticate the sender of the message can still be perfectly viable, depending on the level of security provided by the transport protocol.

Integrity Through Signing

As we’ve said, the WS-Security specification provides a framework for security. The details about how to ensure the integrity of the messages that are sent are contained in the W3C XML Signature Syntax and Processing recommendation (at http://www.w3.org/TR/ xmldsig-core/). This is quite a weighty document, at over 60 pages, and trying to distill the entire recommendation into a couple of paragraphs (or even a couple of pages) would be nearly impossible. Therefore, we’ll just look at how the recommendation applies to X509 certificates.

Note

When you sign a message using X509 certificates, a hash is generated of the content of the message. This hash value is then encrypted using the private key of the X509 certificate and attached to the message. Because of the way X509 certificates work, only the public key of the X509 certificate can verify that the private key was used for encryption. If you can verify that the private key was used for encryption, you can be sure of the integrity of the message. The recipient of the message also generates the hash value for the content of the message and compares this to the hash value that was received and then decrypted. If the two hash values don’t match, message integrity has been lost—the message might have been intentionally altered by a hacker, it might have been corrupted, or something else might have occurred to modify the message. Whatever has happened to the message, it isn’t the same as when it was sent and should be rejected.

When you sign a message using WSE and X509 certificates, it is advisable to add the public part of the X509 certificate to the message. This allows the recipient of the message to immediately verify the signature of the message without having to retrieve the public key of the X509 certificate from a public key server. When we add the public part of the X509 certificate, we add a <wsse:BinarySecurityToken> element to the <wsse:Security> SOAP header.

<wsse:BinarySecurityToken ValueType="wsse:X509v3"  EncodingType="wsse:Base64Binary"  xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"  wsu:>   MIIBuj...N5jy8= </wsse:BinarySecurityToken> 

A <Signature> element is also added as defined in the XML Signature Syntax and Processing recommendation. This element contains the details of the signature and points to the key needed to verify the signature.

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">   <SignedInfo>     <CanonicalizationMethod      Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />      <SignatureMethod      Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />      <Reference URI="#Id-64ebe2b9-c5a6-4730-afcb-407e3da6c1fc">       <Transforms>         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />        </Transforms>       <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />        <DigestValue>PTo973... LIxYCg=</DigestValue>      </Reference>   </SignedInfo>   <SignatureValue>c4ux/X.../xHwA=</SignatureValue>    <KeyInfo>     <wsse:SecurityTokenReference>       <wsse:Reference        URI="#SecurityToken-8a104aa6-b736-44ab-a768-5b0a5a6c018f" />      </wsse:SecurityTokenReference>   </KeyInfo> </Signature>

A discussion of all of the elements specified here is beyond the scope of this chapter. Full details of these elements, as well as the elements not used here, can be found in the W3C recommendation. We’ll only briefly look at the elements used here:

  • <SignedInfo> Contains the details of how the signature is generated in the <CanonicalizationMethod> and <SignatureMethod> elements.

  • <Reference> This element within <SignedInfo> details the element that is signed, and the URI attribute contains the unique identifier that identifies the signed element.

  • <SignatureValue> Contains the actual signature for the message.

  • <KeyInfo> Allows details specifying the location of the key that is needed to verify the signature. If you added the public key of the X509 certificate to the message, this element will contain a <wsse:SecurityTokenReference> element that points at the correct <wsse:BinarySecurityToken> element.

When you sign the message, the body of the message changes very little; all that is added is a wsu:Id attribute that allows the link between the signature and the signed element to be established:

<soap:Body wsu:  xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">   <Echo xmlns="http://www.notashop.com/wscr">     <strMessage>THIS IS A TEST MESSAGE</strMessage>    </Echo> </soap:Body> 

Confidentiality Through Encryption

In addition to ensuring that a message hasn’t been changed, you might also want to ensure that only the recipient of the message can see what the message contains. You can accomplish this by encrypting the contents of the message. As with signing a message, the actual details of how to encrypt a message are contained in a W3C recommendation—in this case the XML Encryption Syntax and Processing recommendation (at http:/ /www.w3.org/TR/xmlenc-core/). Although not as large as the signature recommendation, this document still comes in at nearly 50 pages. We’ll look only at the basics of how to encrypt messages using X509 certificates.

Note

When you encrypt a message using X509 certificates, the body of the message is encrypted using the public key of the message recipient. Due to the way X509 certificates work, only the private key of the X509 certificate can decrypt a message that was encrypted using the public key.

To encrypt a message, you add an <xenc:EncryptedKey> element to the message. This element contains all of the details needed to decrypt the message, except for the encryption algorithm used:

<xenc:EncryptedKey Type="http://www.w3.org/2001/04/xmlenc#EncryptedKey"  xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">   <xenc:EncryptionMethod    Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">       <wsse:SecurityTokenReference>         <wsse:KeyIdentifier ValueType="wsse:X509v3">           kMhUMx...AoBTw=         </wsse:KeyIdentifier>        </wsse:SecurityTokenReference>     </KeyInfo>     <xenc:CipherData>       <xenc:CipherValue>JeTKQL...=</xenc:CipherValue>      </xenc:CipherData>     <xenc:ReferenceList>       <xenc:DataReference        URI="#EncryptedContent-8e7ec57a-5911-4f42-8a96-317eac913ad5" />      </xenc:ReferenceList>   </xenc:EncryptedKey>  

As with signing, a discussion of all of the elements specified here is beyond the scope of this chapter. Full details of these elements, as well as the elements not used here, can be found in the W3C recommendation. We’ll look only briefly at the elements used here:

  • <KeyInfo> Contains the details of the public key that was used to encrypt the message. Rather than point at a <wsse:BinarySecurityToken> element, you actually store the identifier of the public key in a <wsse:KeyIdentifier> element. This is not the complete public key; it is a pointer that the recipient can use to determine which key was used to encrypt the message.

  • <xenc:ReferenceList> Used in the same way as the <Reference> element when you sign the message and the URI attribute of the <xenc:DataReference> element points at the encrypted part of the message.

When you encrypt a message (as opposed to when you simply sign a message), the entire contents of the message are modified. Or, more precisely, the content of the <soap:Body> element is replaced by a <xenc:EncryptedData> element:

<soap:Body xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"  wsu:>   <xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Content"        xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">     <xenc:EncryptionMethod      Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />      <xenc:CipherData>       <xenc:CipherValue>IiyPs7...oZmA==</xenc:CipherValue>      </xenc:CipherData>   </xenc:EncryptedData> </soap:Body>

The <xenc:EncryptedData> element contains an encrypted version of the body of the message. The <xenc:EncryptionMethod> element contains details about the encryption algorithm used, and the <xenc:CipherData> element contains the actual encrypted version of the body within the <xenc:CipherValue> element.

Signing and Encrypting Messages

Although we’ve looked separately at signing messages and encrypting messages, it is possible to both sign and encrypt the same message.

When you send a message, it is signed before it is encrypted; when the message is received, it must be decrypted before the signature is verified. If you attempt to do these in the wrong order, the signature check will fail because the encrypted version of the message body will have a different signature than the unencrypted version.

WS-Timestamp

As we mentioned earlier, WS-Timestamp is not a specification document in its own right but is still important in the grand scheme of things. It is often called a specification in various documents, so we’ll treat it as such.

The WS-Timestamp specification defines a new element, <wsu:Timestamp>, that allows timing information to be added to messages.

Note

The WS-Timestamp specification was first released in the Security Addendum published by IBM, Microsoft, and VeriSign on August 20, 2002. This version of the specification is in the http://schemas.xmlsoap.org/ws/2002/07/utility namespace and usually takes the wsu prefix.

The <wsu:Timestamp> Element

The structure of the <wsu:Timestamp> header is as follows:

<wsu:Timestamp>   <wsu:Created ValueType="...">...</wsu:Created>   <wsu:Expires ValueType="...">...</wsu:Expires>   <wsu:Received Actor="..." Delay="..." ValueType="...">...</wsu:Received>      <wsu:Received Actor="..." Delay="..." ValueType="...">...</wsu:Received> </wsu:Timestamp>

The <wsu:Created> and <wsu:Expires> elements can be added by the sender of the message. They indicate the time that the message was created and the time that it should be considered expired. You can also specify the ValueType attribute, which indicates the type of time data; if you don’t specify it, it will default to xsd:dateTime, which is suitable for most purposes.

The <wsu:Timestamp> header can also contain multiple <wsu:Received> elements, which contain details of any intermediaries that the message passed through on the way to the ultimate recipient. You can have one <wsu:Received> element for each intermediary that the message passed through. In addition to the ValueType attribute, this element can also have the Actor and Delay attributes. Actor is a required attribute and matches the details in the <wsrp:via> element as specified in the WS-Routing specification (described shortly). The Delay attribute is used to express, in milliseconds, the delay incurred by the message because of this intermediary.

For all three elements, you specify the time as the content of the element, in UTC format.

WS-Routing and WS-Referral

We’ve covered three of the specifications implemented by WSE, and now it’s time to look at the other two. We’ll talk about both in this section. They rely so much on each other that it is next to impossible to talk about one without talking about the other.

Having said that, you can use one specification without the other. In fact, you can use WS-Routing with a different configuration mechanism, and you can use WS-Referral with another path control model. Granted, no specifications are available that you can use instead of WS-Routing and WS-Referral, but the opportunity is there for someone to write them.

WS-Routing

The WS-Routing specification defines a mechanism for exchanging messages between a sender and a recipient via a set of intermediaries. In addition to defining the forward path for these messages, the specification also defines an optional reverse path that you can use to enable two-way messaging that can be used when the underlying transport protocol does not have an intrinsic return path.

Note

The WS-Routing specification is a Microsoft-only specification. It was released as a replacement for the SOAP-RP specification on October 23, 2001. This specification is in the http://schemas.xmlsoap.org/rp/ namespace and usually takes the wsrp prefix.

WS-Routing defines a platform-neutral mechanism for routing messages from an initial sender to an ultimate recipient via any number of intermediaries. You define a SOAP header, <wsrp:path>, that specifies the complete routing details for the message, and you define a set of rules that must be followed to route the message along the specified path.

Although we have three different definitions for the points that a message will take from the sender to the receiver (sender, recipient, and intermediary), all of them can be considered endpoints, and they all follow the same rules for routing the message. Only when the endpoint processes the <wsrp:path> element and applies the routing rules does it know what it should do with the message and which of the three types of endpoint it ultimately belongs to.

The WS-Routing specification is transport neutral and can be bound to any transport protocol. Unlike with the other specifications, the transport protocols you can use are lower-level than SOAP—SOAP is not strictly a transport protocol because it sits on an underlying transport (such as HTTP, TCP, FTP, or SMTP). At the moment, you can build only Web services that operate across the HTTP protocol, although the WS-Routing specification defines bindings for the TCP and UDP protocols as well.

<wsrp:path> element

The <wsrp:path> element is at the heart of what you can do with the WS-Routing specification. It is added to the SOAP header of the message to be routed. This element allows you to specify where a message is from, where it is going, and the route it should take from the initial sender to the ultimate recipient.

The complete structure of the <wsrp:path> element is as follows:

<wsrp:path>   <wsrp:action>...</wsrp:action>   <wsrp:from>...</wsrp:from>     <wsrp:to>...</wsrp:to>   <wsrp:fwd>     <wsrp:via>...</wsrp:via>          <wsrp:via>...</wsrp:via>   </wsrp:fwd>   <wsrp:rev>     <wsrp:via>...</wsrp:via>          <wsrp:via>...</wsrp:via>   </wsrp:rev>   <wsrp:id>...</wsrp:id>   <wsrp:relatesTo>...</wsrp:relatesTo> </wsrp:path>

It’s not hard to tell what a lot of the elements do, but for others the meaning is not so clear. We’ll look briefly at each element.

The <wsrp:action> element indicates the intent of the message, much like the SOAPAction HTTP header does. It must be added by the initial sender of the message and shouldn’t be modified on its path to the ultimate recipient.

As their names suggest, the <wsrp:from> and <wsrp:to> elements specify the initial sender and the ultimate recipient of the message, respectively, and both are optional. If you don’t specify them, the details in the <wsrp:fwd> and <wsrp:rev> elements will be used to route the message, as you’ll see when we look at the routing rules.

The <wsrp:fwd> and <wsrp:rev> elements specify the forward and reverse paths for the message, respectively—with the caveat that if the transport protocol has an intrinsic reverse path, as is the case with HTTP, you don’t need to specify the reverse path. Both of these elements contain child <wsrp:via> elements that contain an ordered list of intermediaries between the initial sender and the ultimate recipient of the message.

The final two elements are <wsrp:id> and <wsrp:relatesTo>. The <wsrp:id> element is required; it specifies a unique ID for the message. The <wsrp:relatesTo> element specifies that a message has some relationship with another message—for example, that it is the response to a request.

The routing rules

Now that we’ve looked at the <wsrp:path> element, it’s time to look at the rules that determine how the message is actually routed. Only two sets of rules are actually used for routing—the sending rules that are followed when a message is sent and the receiving rules that are followed when a message is received. The initial sender of the message will folllow only the sending rules and the ultimate recipient will follow only the receiving rules. However, as we’ll shortly see, an intermediary will follow the receiving rules first, then the sending rules.

When creating a message for routing, the sender must ensure that a route is specified in the message—either in the <wsrp:to> element, the <wsrp:fwd> element, or a combination of the two. The message must be sent first to the <wsrp:via> element in the <wsrp:fwd> element, and if there is no <wsrp:fwd> element, the message must be sent to the <wsrp:to> element.

When a message is received that has a <wsrp:path> header in the SOAP header, it has either reached its ultimate destination or it needs to be routed to the next endpoint. The process depends on whether there is a <wsrp:fwd> element in the <wsrp:path> header.

  • If no <wsrp:fwd> element is present or the element contains no <wsrp:via> elements, the message has probably reached its ultimate destination and you must look at the <wsrp:to> element. If the <wsrp:to> element matches the current endpoint, the message has reached its ultimate destination. If the <wsrp:to> element does not exist or does not match the current endpoint, an error has occurred and a fault must be sent back to the initial sender.

  • If a <wsrp:fwd> element is present and contains one or more <wsrp:via> elements, the message must be routed. If the first <wsrp:via> element does not indicate the current endpoint, an error has occurred and a fault must be returned to the original sender. If the first <wsrp:via> element does match the current endpoint, you might have to route the message to another endpoint. If any other <wsrp:via> elements are present or if the message contains a <wsrp:to> element, this endpoint is an intermediary and the rules described in the next list must be followed. If neither of these elements can provide details of an endpoint, the current endpoint is the ultimate destination.

When the two previous rules are followed, an endpoint can determine whether it is an intermediary. It is an intermediary if it has to send the message on to another endpoint. In this case, it must also follow these additional rules:

  • The intermediary must remove the <wsrp:via> element referring to itself from the <wsrp:fwd> element.

  • The intermediary can add extra endpoints to the forward path. You can use custom logic to determine the extra endpoints, or you can use details provided by the WS-Referral specification to determine those extra endpoints.

  • If a <wsrp:rev> element is present, the <wsrp:via> element that was removed from the <wsrp:fwd> element should be placed first in the <wsrp:rev> element, before any existing <wsrp:via> elements.

  • If one or more <wsrp:via> elements are in the <wsrp:fwd> path, you must send the message to the address specified in the first <wsrp:via> element.

  • If no <wsrp:via> elements are in the <wsrp:fwd> path, you must send the message to the address specified in the <wsrp:to> element.

These rules might seem complex, but as you’ll see when we look at routing in Chapter 14, they provide a lot of scope for routing messages and performing various processing tasks at the intermediaries along the way.

WS-Referral

You know from our discussion of WS-Routing how messages are routed and how the routing information is added to the message in the <wsrp:path> element. WS-Referral is a complementary specification that allows you to amend routing details for an endpoint.

Note

The WS-Referral specification is a Microsoft-only specification and was released on October 23, 2001. This specification is in the http://schemas.xmlsoap.org/2001/10/referral/ namespace and usually takes the r prefix.

With WS-Referral, you can modify the routing details for an endpoint and delegate a given URL or part of a URL to a different endpoint than that originally specified. What WS-Referral does not do is guarantee the trustworthiness of the information specified— you have to implement a separate trust mechanism to verify that the WS-Referral details can be trusted.

The WS-Referral specification defines the <r:ref> element, which you can use to specify the configuration details for a router. We’ll briefly discuss the structure of this element in a moment, and you’ll see it in action in Chapter 14 when we look at server-controlled routing.

The WS-Referral specification also defines mechanisms for endpoints to query other endpoints for their routing information and for endpoints to request that the routing information for an endpoint be modified. These are quite advanced topics. The current release of WSE doesn’t support that functionality, so you can refer to the specification for a description of these mechanisms.

<r:ref> element

The <r:ref> element appears complex at first but is really very simple. Its structure is as follows:

<r:ref>   <r:for>     <r:exact>...</r:exact>     <r:prefix>...</r:prefix>   </r:for>   <r:if>     <r:ttl>...</r:ttl>   </r:if>   <r:go>     <r:via>...</r:via>   </r:go>   <r:refId>...</r:refId>   <r:desc>     <r:refAddr>...</r:refAddr>   </r:desc> </r:ref>

This might look complex, but it can be summarized as “if the conditions in the <r:for> element are met, send the message to one of the <r:via> child elements of the <r:go> element.” You can easily tell what many of the child elements of <r:ref> actually do, but for completeness we’ll briefly describe each of them.

The <r:for> element contains the details of the addresses this referral instruction applies to. The <r:exact> element specifies an exact URL, and the <r:prefix> element specifies the start of a URL to which you want all matching requests to be routed.

The <r:if> element specifies the conditions under which you want the referral instruction to be valid. The <r:ttl> element specifies the time, in milliseconds, that the referral instruction is valid—after the specified time, the referral instruction is discarded.

The <r:via> child elements of <r:go> specify the routes that a message can take from this endpoint. If multiple <r:via> elements are present, the endpoint can choose which <r:via> element to route the message to—the order of the <r:via> elements is irrelevant.

The <r:refId> element supplies a unique identity for this referral instruction. It is required.

The final element in the referral instruction, <r:desc>, can contain useful additional information about the WS-Referral statement.

There is another element that we haven’t shown. The <r:if> element has another possible child element, <r:invalidates>, as shown here:

  <r:if>     <r:invalidates>       <r:rid>...</r:rid>     </r:invalidates>   </r:if>

You can use the <r:invalidates> element to change the existing routing details by either removing the details altogether or specifying a replacement for an existing route. By specifying the ID that was used in the <r:refId> element for the <r:rid> element, you can replace the route that was previously defined. If you have a <r:via> element in the <r:go> element, the existing route is replaced and if you have an empty <r:go> element, the route will be removed.




Programming Microsoft. NET XML Web Services
Programming MicrosoftВ® .NET XML Web Services (Pro-Developer)
ISBN: 0735619123
EAN: 2147483647
Year: 2005
Pages: 172

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net