Securing XML Web Services

XML Web services require as much, if not more, security than any other type of application. You’ve already learned, in the previous two chapters, the basic concepts of security within the .NET Framework. In addition to those methods, you can implement custom Simple Object Access Protocol (SOAP) headers to pass a username and a password with the SOAP request. If you’re going to be sending security credentials, potentially over the Internet, you’ll probably want to encrypt the data in transit.

In this section, we introduce you to authentication and authorization, as well as the techniques that you can utilize to implement them. Later in this section we show you how to implement security by using custom SOAP extensions as well as encrypting the data containing the security information.

Using Authentication Techniques

In the .NET Framework, authentication is the process of discovering and verifying the identity of a principal by examining credentials against some authority. Now, you will learn about Windows, Forms, and Passport authentication as well as how to create additional headers to your XML Web service in order to implement custom authentication.

Implementing Windows Authentication

Windows authentication enables you to utilize your existing Windows users and groups to provide access to your XML Web services. Internet Information Server (IIS) provides three ways to implement the authentication of the request:

Basic authentication   Transmits passwords in clear text (Base64 encoded), causing a security risk. Basic authentication is compatible with most web browsers.

Digest authentication  Hashes and then transmits passwords. Digest authentication is supported by Internet Explorer 5 and above.

Integrated Windows authentication   Transmits passwords that are hashed when using Windows NT LAN Manager (NTLM) challenge/response or a Kerberos ticket when Kerberos is used. Integrated Windows authentication cannot pass through proxy or firewall servers without using Virtual Private Network (VPN) technology.

In order to configure the application to use Windows authentication, you must set the authentication mode in the web.config file as follows:

<system.web>   <authentication mode="Windows" /> </system.web>

Implementing ASP.NET Authentication

In addition to Windows authentication, ASP.NET has built-in support for Forms and Passport authentication. At the moment, Forms and Passport authentication are not recommended for XML Web services authentication. Instead you should use Windows authentication, or implement a custom authentication scheme. In the future, Passport authentication might become a more appropriate choice for XML Web service authentication.

Forms authentication occurs when an unauthenticated request is redirected to an HTML logon form. The requester supplies credentials to the form and submits it to the server, where it is verified. Having the Web request redirected to a user interface (UI), such as a Web form, where the requester enters their credentials which is not conducive to the nature of an XML Web service.

Passport authentication is a centralized authentication service provided by Microsoft. Passport’s best feature is that it allows for a single sign-on that can be used on multiple resources across the Web. One of the most popular sites that utilizes Passport authentication is eBay.

Implementing Custom Authentication by Using SOAP Headers

You could use the techniques you learned previously to authenticate an XML Web service request; however, many of them are not appropriate for authentication over the Internet. Windows authentication, for instance, would require that a Windows user account be created for each and every consumer of the XML Web service. A more conducive solution would be to store the credentials in a database, such as Microsoft SQL Server, and validate the credentials supplied in the request against those stored in the database.

One of the best approaches to passing additional data with a request to an XML Web service is a SOAP header. User and password information are added to the SOAP header by the Web service consumer and are passed to the XML Web service. After the header is retrieved, the Web service would carry out custom authentication.

To create a custom SOAP header, you define the class that inherits from the SoapHeader class. Located in the System.Web.Services.Protocols namespace, SoapHeader represents the content of a SOAP header. The following example demonstrates deriving a class from the SoapHeader class:

Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.Xml Imports System Public Class AuthenticationHeader     Inherits SoapHeader     Public UserName As String     Public Password As String End Class

After you have created the custom SOAP header, you must create an instance of it to add to the Web method. The following example creates an instance of the AuthenticationHeader class defined previously and applies it to the Web method:

Dim AuthHead As AuthenticationHeader <WebMethod(), SoapHeader("AuthHead", Required:=True)> _   Public Function HelloWorld() As String         'Code to validate incoming username and password    Return  "Hello World"   End Function 

Of course, if your intention is to implement your own custom authentication, you must disable ASP.NET authentication in the web.config file for your XML Web service. The mode attribute of the <authentication> element should be set to None. This is demonstrated in the following example:

<configuration>   <system.web>     <authentication mode = "None" />   <system.web> </configuration>

In Exercise 11.2, you will derive a class from the SoapHeader class in order to pass the consumer’s credentials in the SOAP header.

Exercise 11.2: Using Custom SOAP Headers for Authentication

start example
  1. Create a new ASP.NET Web Service project named SOAPAuthExample and switch to Code view.

  2. Add the following Imports statements to the top of the code file:

    Imports System.Web.Services.Protocols Imports System.Web.Services Imports System.Xml Imports System
  3. Add the following code to the code file in order to create a custom SOAP header to pass the authentication information:

    Public Class AuthenticationHeader     Inherits SoapHeader     Public UserName As String     Public Password As String End Class
  4. The following code should be added to the Service1 class to create a Web method called myTime that returns a string and implements the custom header:

    Public AuthHead As New AuthenticationHeader() <WebMethod(), SoapHeader("AuthHead", Required:=True)> _ Public Function myTime() As String End Function 
  5. Verify that the username passed in is Customer and that the password supplied is p@$$W0rD by adding the following code within the myTime Web method:

    If AuthHead.UserName = "Customer" And AuthHead.Password = "p@$$W0rD" Then     Return Now.ToLongTimeString Else     Throw New Exception("Access Denied") End If

  6. Build the SOAPAuthExample solution and add a new Windows Application project by right-clicking the SOAPAuthExample solution and choosing Add Ø New Project. Name the project SOAPAuthExample_Client.

  7. Drag two TextBox controls named txtUsername and txtPassword onto Form1 by using these details:

    • Name: txtUsername, Text: Username

    • Name: txtPassword, Text: Password

  8. Drag a Button control onto the form named btnCallService with a Text property of Call Service. The following form represents how Form1 should appear.

  9. From the Solution Explorer, right-click the References item under the SOAPAuthExample_Client project and choose Add Web Reference.

  10. In the Add Web Reference dialog box, type the following URL into the Address field: http://ServerName/Exercise11_2/Service1.asmx. (ServerName should be replaced with LocalHost or the name of the server you are developing on.)

  11. After the Available References window fills, click the Add Reference button to create the proxy class in the project.

  12. Double-click the Call Service button to add an event handler for its Click event and switch to Code view.

  13. Add the following code to instantiate the proxy class and invoke the Web service. You’ll pass the values of the text boxes as the username and password arguments for the Web method:

    Dim proxy As New localhost.Service1() Dim Credentials As New localhost.AuthenticationHeader() Credentials.UserName = txtUsername.Text Credentials.Password = txtPassword.Text Try     proxy.AuthenticationHeaderValue = Credentials     MessageBox.Show(proxy.myTime()) Catch exc As Exception     MessageBox.Show(exc.Message) End Try
  14. From the Solution Explorer, right-click the SOAPAuthExample_Client project and choose the Set As StartUp Project option.

  15. Launch the SOAPAuthExample_Client project and click the Call Service button, leaving the contents of the text boxes untouched—Username and Password—and obviously incorrect which causes the following message box to appear.

    click to expand

  16. Click OK on the message box and type the following values in the respective text boxes.

    • Username: Customer

    • Password: p@$$W0rD

  17. Click the Call Service button again, now with the correct values for the username and password.

  18. Close the form and save and close the Visual Studio projects.

end example

Now that you’ve learned some ways to authenticate the calls to your Web service, you need to learn how to determine who can and cannot execute the service.

Using Authorization Techniques

Authorization is the means of establishing whether a principal, or user, is allowed to complete a requested action. Authorization occurs after authentication, utilizing the requesting user’s identity and role membership to determine which resources the user is allowed to access. There are two predominant techniques for authorizing the use of an XML Web service: file- and URL-based authorization.

File-Based Authorization

File-based authorization uses NTFS file security to determine whether the requesting client can access the resource. The only time that this can be used is when you are using Windows authentication. The actual authorization is performed by the file authorization module; it performs a check against the access control list (ACL) to establish the permissions that the user should have. This combines with impersonation to allow ASP.NET to make requests for resources by using the credentials of the client application that initiated the request.

Instead of implementing your own authentication and authorization scheme, you can use impersonation to let IIS authenticate the user, passing either an authenticated token to the ASP.NET application or an unauthenticated token (Anonymous). ASP.NET will then, relying on impersonation, use the token provided by IIS to access the resource.

To apply this technique to an XML Web service, you assign specific NTFS permissions to the .asmx file (or the directory that contains it).

Note 

In Exercise 11.3, you will secure your XML Web service by using file-based authorization.

Warning 

File-based authorization can be implemented only on an NT-based operating system (such as Windows 2000, Windows XP, or Windows Server 2003), with the project files being saved in a directory on an NTFS-formatted volume.

URL-Based Authorization

URL-based authorization uses <allow> and <deny> elements in the application’s web.config file to grant or deny access based on the ASP.NET URI that the client is requesting and the identity associated with the request. The authorization elements are located within the <authorization> element of the web.config.

You can allow or deny users access by using the users, roles, and verb attributes. The users and roles attributes have a value of a comma-delimited list of users and roles, respectively. In addition to listing the users and roles, you can use specific symbols that indicate a special meaning. The question mark (?) represents anonymous, or unauthenticated users, and the asterisk (*) represents all users. The first match to the identity of the request will apply. For this reason, you should put the <deny> elements at the top of the <authorization> element.

The following example prevents anonymous access and access by members of the Consultants and Temps roles to the resources of this application, while granting access to members of the Managers role and the Admin user:

  <system.web>     <authorization>         <deny users="?" roles="Consultants, Temps" />         <allow users="Admin" roles="Managers" />     </authorization>   </system.web>

As you can see in the preceding example, you can specify the authorization settings for all the resources within the main application folder by placing your authorization details within the <authorization> element in the main <system.web> element of the web.config file. In addition, you can configure different authorization rules on each resource by adding a <location> element within the <configuration> element of the web.config file. The following example specifies authorization rules for myService.asmx:

<location path="myService.asmx" >   <system.web>     <authorization>         <deny users="?" roles="Guests" />         <allow users="Thatcher" roles="Employees" />     </authorization>   </system.web> </location> 

You can also specify a subfolder as the resource, as in the following sample:

<location path="ChildDirectory" >   <system.web>     <authorization>         <deny users="?" roles="Guests" />         <allow users="Thatcher" roles="Employees" />     </authorization>   </system.web> </location>

In addition to permitting or denying certain users to access specific files or folders, you can also authorize which verbs are allowed to be used with each of the services. You can specify GET or POST by including the following type of elements within the <authorization> element:

<location path="myService.asmx" >   <system.web>     <authorization>         <deny verb="GET" users="*" />         <allow verb="POST" users="*" />     </authorization>   </system.web> </location>

The preceding example prevents anyone from using HTTP GET to invoke the myService.asmx Web service and allows all users the ability to use HTTP POST.

The proxy class, when created with Visual Studio .NET or the WSDL.exe tool, exposes the Credentials property that you can set to a NetworkCredential object in order to pass credentials to be validated against password-based authentication schemes such as basic, digest, NTLM, and Kerberos authentication. The following example depicts assigning a new NetworkCredential object to the Credentials property of the proxy class:

Dim proxy As New localhost.Service1() proxy.Credentials = _      New Net.NetworkCredential("username", "password", "DomainName")

The domain name parameter is optional and refers to the Windows domain that is doing the authentication. In Exercise 11.3, you will create a Web service and restrict access by using URL-based authorization.

Note 

Exercise 11.3 requires Windows 2000, Windows XP, or Windows 2003 Server in order to support the creation of Windows accounts in the exercise.

Exercise 11.3: Implementing File-Based Authorization

start example
  1. Open a command prompt by clicking Start Ø Run and typing cmd.exe in the Run text box.

  2. At the prompt, type the following commands to create two user accounts on your local machine (press Enter after each command):

    net user /add user1 p@$$W0rD net user /add user2 pAsSwOrD
  3. Type exit and press Enter at the command prompt to close the window.

    click to expand

  4. Create a new XML Web service project named FileBasedAuthExample and switch to Code view.

  5. Use the following code to create a Web method named secretMessage:

    <WebMethod()> Public Function secretMessage() As String     Return "Secret Message to " & User.Identity.Name.ToString() End Function

  6. Add a new XML Web service named Service2.asmx to the project and switch to its Code view.

  7. Use the following code to create a Web method named publicMessage in the Service2.asmx code file:

    <WebMethod()> Public Function publicMessage() As String     Return "Public Message to " & User.Identity.Name.ToString() End Function

  8. Open the project’s web.config file and notice that the authentication mode is set to Windows:

    <authentication mode="Windows" />
  9. Remove the <authorization> element and its contents from the web.config file.

  10. Add the following code on the line before the closing </configuration> element of the web.config file to permit User2 to execute the secretMessage service while preventing User1 from accessing the Service1.asmx service (replace ComputerName with the name of the computer you created the users on):

      <location path="Service1.asmx">     <system.web>         <authorization>             <deny users="?" />             <deny users="ComputerName\User1" />             <allow users="ComputerName\User2" />             </authorization>     </system.web>   </location>   <location path="Service2.asmx">     <system.web>         <authorization>             <deny users="?" />             </authorization>     </system.web>   </location>
  11. Build the solution and then right-click the FileBasedAuthExample solution from the Solution Explorer and click Add Ø New Project. Select the Windows Application template and name the new project FileBasedAuthExample_Client.

  12. Drag two Button controls onto Form1 with the following properties and values:

    • Name: btnUser1, Text: User1

    • Name: btnUser2, Text: User2

  13. From the Solution Explorer, right-click the References item under the Exercise11_3_Client project and choose Add Web Reference.

  14. In the Add Web Reference dialog box, type the following URL into the Address field: http://ServerName/Exercise11_3/Service1.asmx. (ServerName should be replaced with LocalHost or the name of the server you are developing on.)

  15. After the Available References window fills, click the Add Reference button to create the proxy class in the project.

  16. From the Solution Explorer, right-click the References item under the Exercise11_3_Client project and choose Add Web Reference.

  17. In the Add Web Reference dialog box, type the following URL into the Address field: http://ServerName/Exercise11_3/Service2.asmx.(ServerName should be replaced with LocalHost or the name of the server you are developing on.)

  18. After the Available References window fills, click the Add Reference button to create the proxy class in the project.

  19. From the Solution Explorer, right-click the localhost Web Reference and rename it to svcSecret.

  20. From the Solution Explorer, right-click the localhost1 Web Reference and rename it to svcPublic.

  21. To create a subroutine in Form1.vb to call both services, use the following code with parameters for the credential information:

    Public Sub CallServices(ByVal strUser As String, ByVal strPassword As String)     Dim proxySecret As New svcSecret.Service1()     Dim proxyPublic As New svcPublic.Service2()     Dim myCredentials As New Net.NetworkCredential(strUser, strPassword)     Try         proxySecret.Credentials = myCredentials         MessageBox.Show(proxySecret.secretMessage())     Catch exc As Exception         MessageBox.Show(exc.Message)     End Try     Try         proxyPublic.Credentials = myCredentials         MessageBox.Show(proxyPublic.publicMessage())     Catch exc As Exception         MessageBox.Show(exc.Message)     End Try End Sub 

  22. Create an event handler for btnUser1 and type the following code in the procedure:

    CallServices("User1", "p@$$W0rD")
  23. Create an event handler for btnUser2 and type the following code in the procedure:

    CallServices("User2", "pAsSwOrD")
  24. From the Solution Explorer, right-click the Exercise11_3_Client project and choose Set As StartUp Project.

  25. Launch the Exercise11_3_Client project.

  26. Click the User1 button to attempt both services as User1, who is denied access to the Secret Web service, but permitted to access the Public service.

  27. Click the User2 button to attempt both services as User2, who is permitted to access both services.

  28. Close the application and save and close Visual Studio .NET

end example

Encrypting SOAP Messages

Now that you have learned about authentication and authorization to prevent unauthorized access, you will need to secure the SOAP message itself. You must secure the contents of the XML Web service in transit between the server and the consumer. You can secure the SOAP messages by encrypting them before sending them.

Here you will be introduced to some of the techniques that you can use to secure all or some of the contents of the SOAP message.

Using SSL

One of the simplest ways to encrypt the SOAP message in transit is to use Secure Sockets Layer (SSL) connections. You need to obtain an X509 certificate from a certificate authority (CA). You must enable SSL on your Web server after you have obtained a certificate. To enable SSL on IIS, you must open Internet Services Manager from the Administrative Tools on your Web server. Right-click the site on which you want to enable SSL and choose Properties. Navigate to the Directory Security tab, as seen in Figure 11. 1, and click the Server Certificate button to launch the Web Server Certificate Wizard.

click to expand
Figure 11.1: IIS Directory Security tab

A major drawback to using SSL to encrypt the contents of a SOAP message is that it limits the protocols that you are able to use as a transport. You can use custom SOAP extensions to encrypt some or all of the SOAP message and still use it with any protocol you choose. Next, you will see the basic steps involved in using custom SOAP extensions for encryption.

start sidebar
Selectively Encrypting Portions of the SOAP Message

You are the Web service developer of an Internet Web service provider. Some of the services that your company will provide require authentication. In some cases, credit card information might need to be transmitted across the Internet to be validated.

Your boss has volunteered you to be responsible for the security and privacy of the data that is being passed. The information must pass from the client to the Web service in a secure fashion. Many of the consumers will be using your Web service in their web applications, and therefore your service will need to perform as quickly as possible so as to not impact your customers’ customers.

You know that using SSL causes all of the communication between the server and the consumer to be encrypted. Encrypting the whole message is not necessary in this case; the only data that must be secure are the authentication credentials and credit card data. Moreover using SSL is often slow because the third party, or CA, needs to be contacted. One of the requirements posed to you is that the service must be as responsive and quick as possible.

You decide to alleviate this problem by creating a custom SOAP extension. By using a SOAP extension, you can encrypt only some of the requests or responses, or even specific parts of the requests or responses. You can also choose the type of encryption you would like to implement.

end sidebar

Implementing Custom SOAP Extensions

The .NET Framework makes it possible to interact with the serializing and deserializing processes for SOAP messages. To do this, you must create a class that is derived from the SoapExtension class, located in the System.Web.Services.Protocols namespace. You must also create a custom attribute that references the SOAP extension class.

To encrypt and decrypt messages by using this technique, you must apply the custom attribute to the appropriate XML Web service methods. A .NET consumer application of the XML Web service could also use the custom attribute. The attribute would need to be applied to the proxy class’s methods that correspond to those services with the attribute applied.

Note 

The complete code for this topic is included on the CD that comes with this book, in the SOAPExtension.zip file. The code is a slightly customized version of sample code that originated from http://www.gotdotnet.com/team/rhoward. Rob Howard, a program manager on the .NET Framework team with Microsoft, makes this and several other .NET samples available for download from his page. This code is used with his permission.

After you inherit from the SoapExtension class, you can intercept the SOAP message in the ProcessMessage procedure, as seen in the following example:

Public Overrides Sub ProcessMessage(ByVal msg As SoapMessage)         Select Case msg.Stage             Case SoapMessageStage.BeforeSerialize              'Nothing needs to happen here             Case SoapMessageStage.AfterSerialize                 'Encrypt the data before serializing it to the client.                 Encrypt()             Case SoapMessageStage.BeforeDeserialize                 'Decrypt the data before                   'deserializing it to .NET objects                 Decrypt()             Case SoapMessageStage.AfterDeserialize              'Nothing needs to happen here             Case Else                 Throw New Exception("Invalid Stage.")         End Select End Sub

To implement selective encryption, you can create a custom attribute that you can apply to individual Web methods to require them to be encrypted. To accomplish this, you would inherit from the SoapExtensionAttribute class.

To enable this encryption on an XML Web service, you need to reference the Encryption assembly and add the attribute to the Web method, as in the following example:

<WebMethod(), EncryptionExtension(Encrypt:=EncryptMode.Response, _     SOAPTarget:=Target.Body)> Public Function ReturnString() As String         Return "This is an encrypted string"     End Function 

The client that uses this XML Web service would also need to use the extension in order to encrypt the request and decrypt the response.

Note 

You can find more information about encryption schemes at http://msdn.microsoft.com and http://www.gotdotnet.com. There are also numerous books on the subject.



MCAD/MCSD(c) Visual Basic. NET XML Web Services and Server Components Study Guide
MCAD/MCSD: Visual Basic .NET XML Web Services and Server Components Study Guide
ISBN: 0782141935
EAN: 2147483647
Year: 2005
Pages: 153

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