XML Web Services

I l @ ve RuBoard

XML Web services is a distributed communications protocol based on SOAP. SOAP can be loosely defined as XML over HTTP. SOAP, among other things, provides a standard that supports the transfer of data in the form of XML messages. Other forms of distributed communication technologies require communication in a much more tightly- coupled fashion, often using platform-specific binary protocol formats. SOAP, thanks to its use of XML and HTTP, frees the client and server from any platform-specific implementation restrictions, allowing much greater flexibility and the use of Web services in a heterogeneous (nonuniform) computing environment.

What ties together the client and a server is a contract. When you develop a Web service, a contract is created that specifies all of the supported headers, methods, parameters, and return types. (This contract is generated automatically by the Visual Basic .NET compiler when you build an ASP.NET Web Service project.) As long as a client honors the contract, that client will be able to successfully communicate with the server. This makes Web services language-independent and platform-independent. Also, because of the flexibility of the XML format, you can add more methods to your service without breaking the functionality of your clients . Unlike tightly-coupled applications, which break easily with the smallest changes, XML Web services are extremely flexible and tolerant of change.

Getting Started

Creating Web services is almost trivial in Visual Basic .NET using the ASP.NET framework. A Web service has access to virtually all of the .NET Framework, including authentication, caching, state management, threading, and COM+. To differentiate Web services from regular ASP.NET applications, which use the .aspx file extension, the .asmx file extension was introduced.

Creating a Web service is as simple as creating a new ASP.NET Web services project through the Visual Basic .NET IDE. From there, all you need to do is customize the default ASMX file created by the IDE. The basic requirements for a Web service in a Web service project include:

  • A class that inherits from the WebService class

  • A method that is marked with the WebMethod attribute

That's about it. Using the default example created by the Visual Basic .NET IDE, a simple Web service might look like this:

 ImportsSystem.Web.Services <WebService(Namespace:= "http://tempuri.org/")>_ PublicClassService1 InheritsSystem.Web.Services.WebService #Region " WebServicesDesignerGeneratedCode " <WebMethod()>PublicFunctionHelloWorld()AsString HelloWorld= "HelloWorld" EndFunction EndClass 

That's about it. All you need to do is compile the Web service, which will generate all of the contract and discovery information needed for a client to consume this service.

Consuming an XML Web Service

To consume a Web service in Visual Basic .NET, you must add a Web reference to your project. A Web reference is a design-time-generated proxy class. This class provides the methods exposed by a WebService and marshals all method calls to the actual Web service at run time. This allows the developer to access the Web service as if it were a local component. This provides several advantages, including support for code completion (IntelliSense) for the methods and properties provided by the service. This proxy class implementation is responsible for enforcing the SOAP contract details for the target Web service. You can add a Web reference to any kind of project.

At run time, every call to the proxy object is converted to a SOAP request and sent to the Web service. The target Web service translates the SOAP request and invokes the specified target method. If the target method returns any information, that data is first translated into a SOAP message and then sent back to the client. On the client, the proxy class is responsible for converting the SOAP message back to a native format before returning the type back to the calling code.

Note

You can use the URL property of the proxy class to specify the destination URL of the XML Web service. The Add Web Reference dialog box defaults the proxy target to the URL of the XML Web service originally selected. This is useful if you need to change the target of a Web service at run time. For example, you might be using one Web service while developing your application but need to easily specify a different service when the application is deployed.


SOAP Header Extensions

Recall that all Web services are based on the SOAP protocol. One interesting feature of SOAP is the ability to support a variable number of headers ”known as SOAP headers ”that can be sent with each SOAP request. SOAP headers offer a way to pass information to and from an XML Web service method without affecting the actual method being invoked. The header can contain user authentication details or other information that you think is important. You can thus send all sorts of information back and forth without having to change the definition of your methods to accept additional parameters.

You can define as many SOAP headers as your application needs, and headers will be applied to individual methods contained within a service. You can easily change what headers are required for which method calls.

To incorporate a SOAP header in the design of your Web service, you must follow these steps:

  1. Create a class that inherits from SoapHeader . This class should contain all of the members that have the information you want to include. You can implement additional header classes to process different types of information. From a design perspective, you should logically group related information into a single SOAP header class.

  2. Add a member your XML Web service class of the type of your new SOAP header class.

  3. Apply a SoapHeaderAttribute to your XML Web service method, specifying the name of the new member variable representing your SOAP header.

  4. In your XML Web service method, add code to process your header (that is, to process the information contained in the incoming header and possibly populate additional information for response back to the client).

  5. In your XML Web service client code, add code to process your header (that is, to populate the header with the information you want to send and possibly process the contents of the header after the method call).

To see how this works, let's walk through a simple implementation using user credentials. First, let's define a class that represents our SOAP header:

 PublicClassMyHeader InheritsSoapHeader PublicUserNameAsString PublicPasswordAsString EndClass 

Fairly simple so far. You can see that the header class MyHeader contains the necessary information to authenticate a user. Now we need to create a Web service that implements this header:

 <WebService(Namespace:="http://tempuri.org/")>_ PublicClassService1 InheritsSystem.Web.Services.WebService #Region " WebServicesDesignerGeneratedCode " PublicUserCredentialsAsMyHeader <WebMethod(),SoapHeader("UserCredentials",Required:=True)>_ PublicFunctionHelloWorld()AsString EndFunction EndClass 

I defined a service called WebService1 that supports a Web method called HelloWorld . Using the SoapHeader attribute, I also indicated that the HelloWorld method supports the UserCredentials SOAP header and, in fact, requires that it be passed. This is a simple way of preventing a client from calling the method without providing the header. Now we need to process the header on the WebServices side to determine whether the user is allow to use this method. The code I added to the HelloWorld method looks like this:

 IfMe.UserCredentials.UserName= "bob" And_ Me.UserCredentials.Password= "password" Then Return "HelloWorld" Else ThrowNewException("Invaliduser.") EndIf 

Simple enough, right? Now all we need to do is set up the client application to call this method and provide the header. First, we need to have an application that contains a Web reference to our service. Once we have that and the MyHeader and Service1 classes are defined, all we need to do is use them. We must create the header class and populate it with the user information:

 DimhdrAsNewlocalhost.MyHeader() hdr.UserName= "bob" hdr.Password= "password" 

All that's left to do at this point is create an instance of the Web service, assign the header, and call the Web method. Note that MyHeader is implemented as a member variable named UserCredentials on the Service1 class in the Web service but is missing from the Service1 class in the client. What's going on here? This is just a quirk. The header is available through the MyHeaderValue property on the client. This actually makes sense because it prevents you from declaring the same header type more than once. It also provides the client with an obvious member to store the MyHeader value. Given this information, the following code should make more sense:

 DimwsAsNewlocalhost.Service1() ws.MyHeaderValue=hdr Console.WriteLine(ws.HelloWorld()) 

You can use this same methodology to implement all sorts of additional headers.

Warning

You should never pass user credentials (name and password) in the clear like this in a real application. This is example is meant to illustrative SOAP headers only. Also, you should always use a strong password. Never use an easily guessed password, especially not the word password . See the upcoming section on security and Chapter 9 for additional information about good security practices.


Performance

Web services and performance can go hand-in-hand. Because Web services are hosted in the IIS application, you automatically get a lot of performance features Granted, you can do all sorts of things to kill your performance, but IIS inherently provides built-in scalability. You can also use operating system features such as clustering ”see Figure 5-1 ”to improve your application's performance by moving to a multimachine system. This is simple to do with Web services, but it is much more problematic with Remoting (unless you also host your remote objects in IIS). You also benefit from the fact that IIS scales well on multiprocessor systems.

Figure 5-1. An example of a clustered Web service.

graphics/f05pn01.jpg

Calling Overhead

The flip side of the performance benefits of Web services is that they incur a lot of calling overhead. This means that each call to a Web service is a relatively expensive process. Recall our discussion of chunky versus chatty COM calls in Chapter 4. The same rationale applies here: the calling overhead is significant, so you should design your Web service to minimize the number of necessary calls. Figure 5-2 illustrates the difference between calling methods in a chatty versus chunky way. The first bar indicates the overhead of a single method call. Note that the network overhead is substantial compared to the amount of time spent executing the actual method.

The third bar demonstrates what the performance picture looks like if you call the same method five times. The overhead of the network calls quickly becomes overwhelming ”notice the performance penalty. The center bar shows what happens if you redesign your method to require only a single call. In this case, you realize a performance benefit because you've increased the amount of work accomplished by that method while keeping the overhead at a fixed cost. This is the best way to handle the situation. You should use serialization, whenever possible, to pass the necessary information back and forth to minimize the total number of remote method invocations.

Figure 5-2. The effects of calling overhead.

graphics/f05pn02.jpg

Limitations of Web Services

Unfortunately, Web services cannot support Interop to single-threaded apartment (STA) COM objects. Unlike ASP.NET, which supports an ASPCOMPAT option to execute the page on an STA thread, Web services cannot alter their executing thread model. All Web services run on free threads, and you cannot change this. This is intentional because high performance of Web services is essential.

Security

Web service security relies on the security features of IIS, including built-in user authentication and content security. You can take advantage of these features, or you can roll your own security implementation. We'll look at each of these options in turn . All of these features are accessible through the IIS MMC plug-in from the Computer Management console or under Administrative Tools on the All Programs menu.

User Authentication

IIS provides full support for authenticating users for any resource available through IIS. You can disallow anonymous access to prevent unauthenticated users from accessing specific resources or all resources by turning off anonymous access at the Web-site level. The authentication methods supported by IIS include the following:

  • Anonymous access (no authentication)

  • Digest authentication (sends a hash value over the network instead of the password)

  • Basic authentication (clear-text password)

  • Integrated Windows authentication (built-in secure challenge-response domain-based security)

Supporting each authentication type is as easy as selecting a check box in a dialog box. All of these authentications mechanisms rely in some way on Windows security and permissions.

Content Security

IIS supports a technology called Secure Sockets Layer (SSL), which is intended to provide secure communication for HTTP. The combination of HTTP and SSL is referred to as HTTPS . HTTPS is essentially content-level encryption ”all communication between the client and server is encrypted. It is not an authentication technology. When a client connects to a server, it establishes a secure connection; you must then authenticate your client. If you're using an authentication method such as Basic authentication, you're strongly advised to use SSL. Period. Whenever you send user credentials over the network in a clear-text format, you run the risk that someone will poach that information directly off the wire. (Yes, it can be done quite easily by someone with the know-how.)

In the IIS administration utilities, you can also indicate what content must use SSL. Typically, if you only enable SSL for a Web site, you can still access the site's content through both HTTP and HTTPS. By marking content as requiring SSL, you prevent user access over HTTP. Not only will this help isolate a potential set of security bugs (typos are easy to introduce when all you're typing is HTTP or HTTPS), but it will completely prevent intentional misuse of that content.

Custom Security

From a pure security perspective, it is always extremely risky to implement your own custom solution. Custom solutions can be more vulnerable than a provided solution, although the vulnerabilities might be less obvious. If you choose to implement a custom solution, you should be aware of the potential consequences. You should also plan for extensive testing of your security features, preferably by someone who's very experienced with computer security and potential vulnerabilities.

Custom authentication

It is not uncommon for Internet-based services to have their own user databases that are separate from standard user authentication mechanisms. Implementing your own authentication methods in this case is essential ”the standard IIS authentication methods will not suffice. Many avenues are available, including using SOAP header extensions.

In a custom SOAP header extension, you can pass a set of security credentials. These credentials can take several forms, including a user ID and password or a session ID. Passing a user ID and password with each call is inherently dangerous. If you do this, you should at least encrypt the header, if not the entire communication (by using SSL). Preferably, you should authenticate once and obtain a session-specific ID over a secure channel. You then pass that session ID in lieu of actual security information. Yet again, the session ID should be encrypted in some manner to ensure that the ID cannot be spoofed.

Custom content security

You can manually encrypt the contents of your Web service requests by combining object serialization with some form of encryption (probably using one of the Crypto service providers from the Cryptography namespace). This offers some performance advantages by allowing you to encrypt only information that needs to be secure, but it requires a lot of extra work when you can simply use SSL. But, this may just fit the bill for you anyway.

I l @ ve RuBoard


Designing Enterprise Applications with Microsoft Visual Basic .NET
Designing Enterprise Applications with Microsoft Visual Basic .NET (Pro-Developer)
ISBN: 073561721X
EAN: 2147483647
Year: 2002
Pages: 103

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