XML Web Service Enhancements


As I mentioned earlier, distributed computing raises new classes of problems, such as security, reliable message delivery, and operational integrity. These infrastructural problems are common to most distributed applications, so it makes sense to solve them on an industry-wide basis. In the case of Web services, solving these problems is not just a case of making a single operating system provide the functionality. Rather, the community of vendors that will support this infrastructure (Microsoft, IBM, Verisign, and a few others) needs to agree on what features will be supported, how they will work together, and what XML syntax will be required. The overall map goes by the name (today; you know how Microsoft changes the names of things) GXA, for Global XML Architecture. An MSDN article by Don Box (now working for Microsoft) in July of 2002 sketched the basic principles. Basically, the industry will agree on an XML syntax for the required infrastructural features and place them into the header of the SOAP packet used in an XML service call.

Microsoft’s new Global XML Architecture (GXA) is intended to be the standard for enhanced features for Web services.

For example, one of the first needs of any distributed-system developer is user authentication, which generally involves presentation of a credential such as a user name and password. The previous example had no standard location and syntax for presenting such information in a SOAP packet. The Web service development consortium has now defined such a standard syntax, which I show (namespaces removed for clarity) in Listing 4-10.

GXA defines a standard XML syntax for infrastructural features such as security.

Listing 4-10: SOAP packet containing authentication information for Web Services Enhancements

start example
<?xml version="1.0" encoding="utf-8" ?> <soap:Envelope> <soap:Header> <wsse:Security soap:mustUnderstand="1" > <wsse:UsernameToken> <wsse:Username>me@here.com</wsse:Username> <wsse:Password Type="wsse:PasswordText">Fido</wsse:Password> <wsse:Nonce>dIPLPzlgHrBMKOu04M5xeQ==</wsse:Nonce> <wsu:Created>2003-01-25T17:36:31Z</wsu:Created> </wsse:UsernameToken> </wsse:Security> </soap:Header> <soap:Body> <GetTime xmlns="http://tempuri.org/"> <showSeconds>false</showSeconds> </GetTime> </soap:Body> </soap:Envelope> 
end example

Inside the SOAP <Envelope> element is a <Body> element, which contains an application’s data, and a <Header> element, which contains infrastructure data. You can see that the <Body> element contains the usual information for a Web service call, such as the name of the function and its parameters. In this simple example, the <Header> element contains a <Security> element. The <mustUnderstand> element tells the receiver that the information in the <Security> element is so important that if the receiver doesn’t understand what to do with it, the call has to fail. Within the <Security> element is a <UsernameToken> element, which contains the user ID and password, along with the time of its creation and a nonce (a unique string identifying this particular login request so that no two of them are identical).

Infrastructural data lives in a Web service packet’s SOAP header.

As you can imagine, distributed-system design requires many, many other features in addition to user ID and password presentation. The Web service development consortium has released several specifications defining the feature set and its XML implementation. Here is a list of the specs. They’re all available from MSDN, among other places:

There are a number of standards for various pieces of Web service infrastructure.

Specification

Description/Use

WS-Attachments

Attaching documents to a SOAP message

WS-Coordination

Coordinating distributed operations through transactions

WS-Policy

Describing XML Web Service requirements, preferences, and capabilities

WS-Referral

Allows dynamic configuration of WS-Routing paths

WS-Routing

Defines paths for routing SOAP messages over a variety of transports

WS-Security

Defines security for all XML Web services. Contains several subspecifications.

Specifications without some sort of implementation are useless piles of paper. Microsoft released the Web Service Enhancement kit in December of 2002, containing early support for WS-Security, WS-Routing, and WS-Attachments. You can download the kit from http://msdn.microsoft.com. I used it to write a sample program demonstrating one small portion of WS-Security, the authentication example that I discussed previously.

Microsoft’s Web Service Enhancement kit is the first implementation of these features.

Suppose I want my GetTime Web service (aren’t you sick of that one by now? I sure am. I’m getting rid of my watch as soon as I finish this book.) to require user authentication so that I can see whether the client has paid his subscription fees before delivering my service’s value. I’d like to implement authentication with a user ID and a password according to the WS-Security standard. To do this implementation, the client (shown in Figure 4-17) has to somehow place the XML elements from Listing 4-10 in its outgoing SOAP packet, and the server has to somehow read the elements and use them. Because the Web service infrastructure has been so successfully hidden from application programmers, it’s not immediately apparent where the code to do this should go.

A WSE Web service example starts here

click to expand
Figure 4-17: The Web Services Enhancement sample client

The Web service infrastructure employs a set of SOAP filters during its input and output operations, as shown in Figure 4-18. A SOAP filter is a piece of code that is invoked by the Web service during the process of sending and receiving a SOAP packet for the purpose of modifying that packet. While an in-depth discussion of SOAP filters is beyond the scope of this book, they’ve existed since version 1 of Web services, and I even wrote a newsletter article in 2001 (available at http://www.rollthunder.com) about how to write your own. Web Service Enhancements are implemented primarily as a series of SOAP filters. Figure 4-19 shows a close-up of the modification process. Note the SOAP Context object that contains information about the filter application process.

SOAP filters are software components that get invoked when sending or receiving SOAP messages.

click to expand
Figure 4-18: Use of SOAP filters in input and output.

click to expand
Figure 4-19: Modification of a SOAP message by filters.

The client-side code is shown in Listing 4-11. To write it, I first had to install the WSE SDK and then import references to Microsoft.Web.Services into my project. Next I generated a proxy for my Web service by importing the WSDL file, as I’ve done in the samples throughout this chapter. After I generated the proxy, I had to change its base class to Microsoft.Web.Services.WebServicesClientProtocol, the WSE class that understands the new client-side XML features. You’ll have to repeat this change every time you regenerate the proxy.

The client uses a new WSE base class for its proxy.

Listing 4-11: Client-side code

start example
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System. EventArgs) Handles button1.Cli ck ’ Create instance of web service proxy ’ set URL entered by user Dim proxy As localhost.Service1 = New localhost.Service1 proxy.Url = textBox1.Text ’ Create security token that will be used by the service proxy ’ Put user ID and password in token Dim token As UsernameToken = New UsernameToken(textBox2.Text, _ textBox3.Text, PasswordOption.SendPlainText) ’ Fetch SOAP context Dim requestContext As SoapContext = proxy.RequestSoapContext ’ Add the security token and request a signature requestContext.Security.Tokens.Add(token) ’ Make call and report results label1.Text = proxy.GetTime(checkBox1.Checked) End Sub 
end example

The first two lines of code are the same as for any Web service. I create the proxy and set its URL. Next I create an object of class UsernameToken. Part of the WSE, this object exists to hold security information. In its constructor I pass the user name and password that the user has entered. Next I fetch the SOAP context via the proxy class method RequestSoapContext, and then I place the token into the context’s collection of security tokens. When I make the Web service method call in the last line of code, the proxy (as always) constructs the SOAP packet for making the call. In this case, however, the WSE proxy has added an output filter that converts the security token into the XML you saw in Listing 4-10 (in addition to some other items, such as a timestamp, which I don’t want to discuss here).

The client places the user name and password into its SOAP context. The SOAP filter automatically formats them into the outgoing packet.

The process on the server side is conceptually similar. The Web service itself is identical to the previous ones, so I won’t bore you with it. The WSE provides a SOAP filter that knows how to strip out the security token and reconstitute the user name and password. We have to somehow tell the server to put in the correct filter. We do this by adding the <soapExtensionTypes> element to the service’s web.config file, as shown in Listing 4-12.

A SOAP filter on the server retrieves user ID and password from the incoming packet.

Listing 4-12: WSE Sample Web.config file

start example
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="microsoft.web.services" type="Microsoft.Web.Services.Configuration.WebServicesConfiguration, Microsoft.Web.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </configSections> <system.web> <webServices> <soapExtensionTypes> <add type="Microsoft.Web.Services.WebServicesExtension, Microsoft.Web.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" priority="1" group="0" /> </soapExtensionTypes> </webServices> </system.web> <microsoft.web.services> <security> <!-- This is the class which will provide the password or password equivalents for the UsernameToken signatures. --> <passwordProvider type="WebServiceEnhancementSvcVB.PasswordProv ider, WebServiceEnhancementSvcVB" /> </security> </microsoft.web.services> </configuration>
end example

When the WSE’s SOAP filter is invoked by an incoming Web service method call, the filter needs to connect to our code to check whether the supplied user name and password are valid. We provide a hook by writing an object that implements the IPasswordProvider interface, which contains a single method, GetPassword, as shown in Listing 4-13. The WSE filter calls our GetPassword method, passing the UsernameToken that it received from the client. We have to return the password that we were expecting for the incoming user name. If this string matches the supplied password, the filter allows the Web service method call to proceed. Otherwise it throws an exception. We tell the filter which hook to use by making entries in the config file, as shown in Listing 4-13. We need to add a <configSections> element so that the WSE will know where to find its configuration settings. And in its configuration settings section, we supply the <passwordProvider> element, which specifies the assembly and the class of our password provider implementation with the type attribute. The process is shown in Figure 4-20.

The filter calls a hook in our code to match user ID and password.

Listing 4-13: Implementation of IPasswordProvider.

start example
Public Class MyOwnPasswordProvider Implements IPasswordProvider Public Function GetPassword(ByVal token As UsernameToken) As String _ Implements IPasswordProvider.GetPassword Return MyOwnPretendToLookUpPassword (token.Username) End Function End Class 
end example

click to expand
Figure 4-20: Password matching process of WSE SOAP filter.

This simple example showed the basic mechanism that will provide enterprise-level features to Web services and the first implementation of the Microsoft software for implementing it. I need to make a few notes here: First, I stripped the example to its barest bones so that you could see how it works with a minimum of distraction. I omitted a number of other security features that a real application needs. For example, I transmitted the password in clear text, which you probably shouldn’t do. The WSE contains support for several types of encryption, and you probably ought to use one. I didn’t sign the SOAP packet to provide a check against tampering or set an expiration time to protect against a playback attack, both of which you also should do. But this example should crack the problem open for you and make it easier to understand the implementation of these other features.

This simple example doesn’t provide industrial- strength security.

Is this the only way of doing Web service security? No, you can still roll your own, as I showed in the previous section. But you’d then have to educate your customer’s programmers and explain how they need to deal with your specific application. It would be different from other Web services that they might need to use, which they will not like.

The WSE is new and its integration with the tools isn’t fantastic. As you start doing more sophisticated stuff, it gets harder to use. It needs more and better wizard support; for example, an option at project generation to prefabricate the IPasswordProvider class and make the relevant config file entries. I have no doubt that these will eventually be developed and that the features necessary for doing industrial-strength distributed computing with Web service will become widespread and easy to use.

WSE will become more important in the future.




Introducing Microsoft. NET
Introducing Microsoft .NET (Pro-Developer)
ISBN: 0735619182
EAN: 2147483647
Year: 2003
Pages: 110

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