Overview Web services are used by an increasing number of companies as they expose products and services to customers and business partners through the Internet and corporate extranets. The security requirements for these service providers are of paramount importance. In some cases, primarily intranet or extranet scenarios where you have a degree of control over both endpoints, the platform-based security services provided by the operating system and Internet Information Services (IIS) can be used to provide point- to-point security solutions. However, the message based architecture of Web services and the heterogeneous environments that span trust boundaries in which they are increasingly being used pose new challenges. These scenarios require security to be addressed at the message level to support cross-platform interoperability and routing through multiple intermediary nodes. Web Services Security (WS-Security) is the emerging security standard designed to address these issues. Microsoft has released Web Services Enhancements 1.0 for Microsoft .NET (WSE), which supports WS-Security and a related family of emerging standards. WSE allows you to implement message level security solutions including authentication, encryption and digital signatures. Note The specifications and standard supported by WSE are evolving and therefore the current WSE does not guarantee it will be compatible with future versions of the product. At the time of this writing, interoperability testing is under way with non-Microsoft toolkits provided by vendors including IBM and VeriSign. Threats and Countermeasures To build secure Web services, know the associated threats. The top threats directed at Web services are: Unauthorized access Parameter manipulation Network eavesdropping Disclosure of configuration data Message replay Figure 1 shows the top threats and attacks directed at Web services. Figure 1. Main Web services threats Unauthorized Access Web services that provide sensitive or restricted information should authenticate and authorize their callers. Weak authentication and authorization can be exploited to gain unauthorized access to sensitive information and operations. Vulnerabilities Vulnerabilities that can lead to unauthorized access through a Web service include: No authentication used Passwords passed in plaintext in SOAP headers Basic authentication used over an unencrypted communication channel Countermeasures You can use the following countermeasures to prevent unauthorized access: Use password digests in SOAP headers for authentication. Use Kerberos tickets in SOAP headers for authentication. Use X.509 certificates in SOAP headers for authentication. Use Windows authentication. Use role-based authorization to restrict access to Web services. This can be done by using URL authorization to control access to the Web service file (.asmx) or at the Web method level by using principal–permission demands. Parameter Manipulation Parameter manipulation refers to the unauthorized modification of data sent between the Web service consumer and the Web service. For example, an attacker can intercept a Web service message, perhaps as it passes through an intermediate node en route to its destination; and can then modify it before sending it on to its intended endpoint. Vulnerabilities Vulnerabilities that can make parameter manipulation possible include: Messages that are not digitally signed to provide tamperproofing Messages that are not encrypted to provide privacy and tamperproofing Countermeasures You can use the following countermeasures to prevent parameter manipulation: Digitally sign the message. The digital signature is used at the recipient end to verify that the message has not been tampered with while it was in transit. Encrypt the message payload to provide privacy and tamperproofing. Network Eavesdropping With network eavesdropping, an attacker is able to view Web service messages as they flow across the network. For example, an attacker can use network monitoring software to retrieve sensitive data contained in a SOAP message. This might include sensitive application level data or credential information. Vulnerabilities Vulnerabilities that can enable successful network eavesdropping include: Credentials passed in plaintext in SOAP headers No message level encryption used No transport level encryption used Countermeasures You can use the following countermeasures to protect sensitive SOAP messages as they flow across the network: Use transport level encryption such as SSL or IPSec. This is applicable only if you control both endpoints. Encrypt the message payload to provide privacy. This approach works in scenarios where your message travels through intermediary nodes route to the final destination. Disclosure of Configuration Data There are two main ways in which a Web service can disclose configuration data. First, the Web service may support the dynamic generation of Web Service Description Language (WSDL) or it may provide WSDL information in downloadable files that are available on the Web server. This may not be desirable depending on your scenario. Note WSDL describes the characteristics of a Web service, for example, its method signatures and supported protocols. Second, with inadequate exception handling the Web service may disclose sensitive internal implementation details useful to an attacker. Vulnerabilities Vulnerabilities that can lead to the disclosure of configuration data include: Unrestricted WSDL files available for download from the Web server A restricted Web service supports the dynamic generation of WSDL and allows unauthorized consumers to obtain Web service characteristics Weak exception handling Countermeasures You can use the following countermeasures to prevent the unwanted disclosure of configuration data: Authorize access to WSDL files using NTFS permissions. Remove WSDL files from Web server. Disable the documentation protocols to prevent the dynamic generation of WSDL. Capture exceptions and throw a SoapException or SoapHeaderException—that returns only minimal and harmless information—back to the client. Message Replay Web service messages can potentially travel through multiple intermediate servers. With a message replay attack, an attacker captures and copies a message and replays it to the Web service impersonating the client. The message may or may not be modified. Vulnerabilities Vulnerabilities that can enable message replay include: Messages are not encrypted Messages are not digitally signed to prevent tampering Duplicate messages are not detected because no unique message ID is used Attacks The most common types of message replay attacks include: Basic replay attack. The attacker captures and copies a message, and then replays the same message and impersonates the client. This replay attack does not require the malicious user to know the contents of the message. Man in the middle attack. The attacker captures the message and then changes some of its contents, for example, a shipping address, and then replays it to the Web service. Countermeasures You can use the following countermeasures to address the threat of message replay: Use an encrypted communication channel, for example, SSL. Encrypt the message payload to provide message privacy and tamperproofing. Although this does not prevent basic replay attacks, it does prevent man in the middle attacks where the message contents are modified before being replayed. Use a unique message ID or nonce with each request to detect duplicates, and digitally sign the message to provide tamperproofing. Note A nonce is a cryptographically unique value used for the request. When the server responds to the client it sends a unique ID and signs the message, including the ID. When the client makes another request, the client includes the ID with the message. The server ensures that the ID sent to the client in the previous message is included in the new request from the client. If it is different, the server rejects the request and assumes it is subject to a replay attack. The attacker cannot spoof the message ID, because the message is signed. Note that this only protects the server from client-initiated replay attacks using the message request, and offers the client no protection against replayed responses. Design Considerations Before you start to develop Web services, there are a number of issues to consider at design time. The key security considerations are: Authentication requirements Privacy and integrity requirements Resource access identities Code access security Authentication Requirements If your Web service provides sensitive or restrictive information, it needs to authenticate callers to support authorization. In Windows environments, you can use Windows authentication. However, where you are not in control of both endpoints, WSE provides authentication solutions that conform to the emerging WS-Security standard. WSE provides a standard framework for using SOAP headers to pass authentication details in the form of user names and passwords, Kerberos tickets, X.509 certificates, or custom tokens. For more information, see the "Authentication" section later in this module. Privacy and Integrity Requirements If you pass sensitive application data in Web service requests or response messages, consider how you can ensure that they remain private and unaltered while in transit. WSE provides integrity checking through digital signatures, and it also supports XML encryption to encrypt sensitive elements of the entire message payload. The advantage of this approach is that it is based on the emerging WS-Security standard and that it provides a solution for messages that pass through multiple intermediate nodes. The alternative is to use transport level encryption through SSL or IPSec channels. These solutions are only appropriate where you are in control of both endpoints. Resource Access Identities By default, ASP.NET Web services do not impersonate, and the least privileged ASPNET process account is used for local and remote resource access. You can use this ASPNET process account to access remote network resources such as SQL Servers that require Windows authentication, by creating a mirrored local account on the database server. Note On Windows Server 2003, the Network Service account is used by default to run Web services. Code Access Security Consider the trust level defined by security policy in your target deployment environment. Your Web service's trust level, defined by its <trust> element configuration, affects the types of resources that it can access and the other privileged operations it can perform. Also, if you call a Web service from an ASP.NET Web application, the Web application's trust level determines the range of Web services it can call. For example, a Web application configured for Medium trust, by default, can only call Web services on the local computer. Input Validation Like any application that accepts input data, Web services must validate the data that is passed to them to enforce business rules and to prevent potential security issues. Web methods marked with the WebMethod attribute are the Web service entry points. Web methods can accept strongly typed input parameters or loosely typed parameters that are often passed as string data. This is usually determined by the range and type of consumers for which the Web service is designed. Strongly Typed Parameters If you use strongly typed parameters that are described by the .NET Framework type system, for example integers, doubles, dates, or other custom object types such as Address or Employee, the auto-generated XML Schema Definition (XSD) schema contains a typed description of the data. Consumers can use this typed description to construct appropriately formatted XML within the SOAP requests that are sent to Web methods. ASP.NET then uses the System.Xml.Serialization.XmlSerializer class to deserialize the incoming SOAP message into common language runtime (CLR) objects. The following example shows a Web method that accepts strongly typed input consisting of built-in data types. [WebMethod] public void CreateEmployee(string name, int age, decimal salary) {...} In the preceding example, the .NET Framework type system performs type checks automatically. To validate the range of characters that are supplied through the name field, you can use a regular expression. For example, the following code shows how to use the System.Text.RegularExpressions.Regex class to constrain the possible range of input characters and also to validate the parameter length. if (!Regex.IsMatch(name, @"^[a-zA-Z'.`-´\s]{1,40}$")) { // Invalid name } using Employees; [WebMethod] // Custom namespace public void CreateEmployee(Employee emp) { ... } The consumer needs to know the XSD schema to be able to call your Web service. If the consumer is a .NET Framework client application, the consumer can simply pass an Employee object as follows: using Employees; Employee emp = new Employee(); // Populate Employee fields // Send Employee to the Web service wsProxy.CreateEmployee(emp); Consumer applications that are not based on the .NET Framework must construct the XML input manually, based on the schema definition provided by the organization responsible for the Web service. The benefit of this strong typing approach is that the .NET Framework parses the input data for you and validates it based on the type definition. However, inside the Web method you might still need to constrain the input data. For example, while the type system confirms a valid Employee object, you might still need to perform further validation on the Employee fields. You might need to validate that an employee's date of birth is greater than 18 years ago. You might need to use regular expressions to constrain the range of characters that can be used in name fields, and so on. Loosely Typed Parameters If you use string parameters or byte arrays to pass arbitrary data, you lose many of the benefits of the .NET Framework type system. You must parse the input data manually to validate it because the auto-generated WSDL simply describes the parameters as string input of type xsd:string. You need to programmatically check for type, length, format, and range as shown in the following example. [WebMethod] public void SomeEmployeeFunction(string dateofBirth, string SSN) { . . . // EXAMPLE 1: Type check the date try { DateTime dt = DateTime.Parse(dateofBirth).Date; } // If the type conversion fails, a FormatException is thrown catch( FormatException ex ) { // Invalid date } // EXAMPLE 2: Check social security number for length, format, and range if( !Regex.IsMatch(empSSN,@"^\d{3}-\d{2}-\d{4}$",RegexOptions.None)) { // Invalid social security number } } XML Data In a classic business-to-business scenario, it is common for consumers to pass XML data that represents business documents such as purchase orders or sales invoices. The validity of the input data must be programmatically validated by the Web method before it is processed or passed to downstream components. The client and the server have to establish and agree on a schema that describes the XML. The following code fragment shows how a Web method can use the System.Xml.XmlValidatingReader class to validate the input data, which, in this example, describes a simple book order. Notice that the XML data is passed through a simple string parameter. using System.Xml; using System.Xml.Schema; [WebMethod] public void OrderBooks(string xmlBookData) { try { // Create and load a validating reader XmlValidatingReader reader = new XmlValidatingReader(xmlBookData, XmlNodeType.Element, null); // Attach the XSD schema to the reader reader.Schemas.Add("urn:bookstore-schema", @"http://localhost/WSBooks/bookschema.xsd"); // Set the validation type for XSD schema. // XDR schemas and DTDs are also supported reader.ValidationType = ValidationType.Schema; // Create and register an event handler to handle validation errors reader.ValidationEventHandler += new ValidationEventHandler( ValidationErrors ); // Process the input data while (reader.Read()) { . . . } // Validation completed successfully } catch { . . . } } // Validation error event handler private static void ValidationErrors(object sender, ValidationEventArgs args) { // Error details available from args.Message . . . } The following fragment shows how the consumer calls the preceding Web method: string xmlBookData = "<book xmlns='urn:bookstore-schema' xmlns:xsi='http://www.w3.org/2001/XMLSchemainstance'>" + "<title>Building Secure ASP.NET Applications</title>" + "<isbn>0735618909</isbn>" + "<orderQuantity>1</orderQuantity>" + "</book>"; BookStore.BookService bookService = new BookStore.BookService(); bookService.OrderBooks(xmlBookData)); The preceding example uses the following simple XSD schema to validate the input data. <?xml version="1.0" encoding="utf-8" ?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:bookstore-schema" elementFormDefault="qualified" targetNamespace="urn:bookstore-schema"> <xsd:element name="book" type="bookData"/> <xsd:complexType name="bookData"> <xsd:sequence> <xsd:element name="title" type="xsd:string" /> <xsd:element name="isbn" type="xsd:integer" /> <xsd:element name="orderQuantity" type="xsd:integer"/> </xsd:sequence> </xsd:complexType> </xsd:schema> The following table shows additional complex element definitions that can be used in an XSD schema to further constrain individual XML elements. Table 1 XSD Schema Element Examples Description <xsd:element name="zip"> Using <xsd:simpleType> <xsd:restriction base="xsd:string"> regular expressions to constrain XML elements Constraining <xsd:element name="Salary"> <xsd:simpleType> <xsd:restriction base="xsd:decimal"> a decimal value to two digits after the decimal point Constraining <xsd:element name="FirstName"> <xsd:restriction base="xsd:string"> the length of <xsd:simpleType> an input string Constraining <xsd:element name="Gender"> <xsd:simpleType> <xsd:restriction base="xsd:string"> input to values defined by an enumerated type SQL Injection SQL injection allows an attacker to execute arbitrary commands in the database using the Web service's database login. SQL injection is a potential issue for Web services if the services use input data to construct SQL queries. If your Web methods access the database, they should do so using SQL parameters and ideally, parameterized stored procedures. SQL parameters validate the input for type and length, and they ensure that the input is treated as literal text and not executable code. Cross-Site Scripting With cross-site scripting (XSS), an attacker exploits your application to execute malicious script at the client. If you call a Web service from a Web application and send the output from the Web service back to the client in an HTML data stream, XSS is a potential issue. In this scenario, you should encode the output received from the Web service in the Web application before returning it to the client. This is particularly important if you do not own the Web service and it falls outside the Web application's trust boundary. <xsd:pattern v <xsd:fractio <xsd:maxLengt <xsd:enumerat Authentication If your Web service outputs sensitive, restricted data or if it provides restricted services, it needs to authenticate callers. A number of authentication schemes are available and these can be broadly divided into three categories: Platform level authentication Message level authentication Application level authentication Platform Level Authentication If you are in control of both endpoints and both endpoints are in the same or trusting domains, you can use Windows authentication to authenticate callers. Basic Authentication You can use IIS to configure your Web service's virtual directory for Basic authentication. With this approach, the consumer must configure the proxy and provide credentials in the form of a user name and password. The proxy then transmits them with each Web service request through that proxy. The credentials are transmitted in plaintext and therefore you should only use Basic authentication with SSL. The following code fragment shows how a Web application can extract Basic authentication credentials supplied by an end user and then use those to invoke a downstream Web service configured for Basic authentication in IIS. // Retrieve client's credentials (available with Basic authentication) string pwd = Request.ServerVariables["AUTH_PASSWORD"]; string uid = Request.ServerVariables["AUTH_USER"]; // Set the credentials CredentialCache cache = new CredentialCache(); cache.Add( new Uri(proxy.Url), // Web service URL "Basic", new NetworkCredential(uid, pwd, domain) ); proxy.Credentials = cache; Integrated Windows Authentication You can use IIS to configure your Web service's virtual directory for Integrated Windows authentication, which results either in Kerberos or NTLM authentication depending on the client and server environment. The advantage of this approach in comparison to Basic authentication is that credentials are not sent over the network, which eliminates the network eavesdropping threat. To call a Web service configured for Integrated Windows authentication, the consumer must explicitly configure the Credentials property on the proxy. To flow the security context of the client's Windows security context (either from an impersonating thread token or process token) to a Web service you can set the Credentials property of the Web service proxy to CredentialCache. DefaultCredentials as follows. proxy.Credentials = System.Net.CredentialCache.DefaultCredentials; You can also use an explicit set of credentials as follows: CredentialCache cache = new CredentialCache(); cache.Add( new Uri(proxy.Url), // Web service URL "Negotiate", // Kerberos or NTLM new NetworkCredential(userName, password, domain)); proxy.Credentials = cache; If you need to specify explicit credentials, do not hard code them or store them in plaintext. Encrypt account credentials by using DPAPI and store the encrypted data either in an <appSettings> element in Web.config or beneath a restricted registry key. Message Level Authentication You can use WSE to implement a message level authentication solution that conforms to the emerging WS-Security standard. This approach allows you to pass authentication tokens in a standard way by using SOAP headers. Note When two parties agree to use WS-Security, the precise format of the authentication token must also be agreed upon. The following types of authentication token can be used and are supported by WSE: User name and password Kerberos ticket X.509 certificate User Name and Password You can send user names and password credentials in the SOAP header. However, because these are sent in plaintext, this approach should only be used in conjunction with SSL due to the network eavesdropping threat. The credentials are sent as part of the <Security> element, in the SOAP header as follows. <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext"> <wsse:UsernameToken> <wsse:Username>Bob</wsse:Username> <wsse:Password>YourStr0ngPassWord</wsse:Password> </wsse:UsernameToken> </wsse:Security> User Name and Password Digest Instead of sending a plaintext password, you can send a password digest. The digest is a Base64–encoded SHA1 hash value of the UTF8–encoded password. However, unless this approach is used over a secure channel, the data can still be intercepted by attackers armed with network monitoring software and reused to gain authenticated access to your Web service. To help address this replay attack threat, a nonce and a creation timestamp can be combined with the digest. User Name and Password Digest with Nonce and Timestamp With this approach the digest is a SHA1 hash of a nonce value, a creation timestamp, and the password as follows. digest = SHA1(nonce + creation timestamp + password) With this approach, the Web service must maintain a table of nonce values and reject any message that contains a duplicate nonce value. While the approach helps protect the password and offers a basis for preventing replay attacks, it suffers from clock synchronization issues between the consumer and provider when calculating an expiration time, and it does not prevent an attacker capturing a message, modifying the nonce value, and then replaying the message to the Web service. To address this threat, the message must be digitally signed. With the WSE, you can sign a message using a custom token or an X.509 certificate. This provides tamperproofing and authentication, based on a public, private key pair. Kerberos Tickets You can send a security token that contains a Kerberos ticket as follows. <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext"> <wsse:BinarySecurityToken ValueType="wsse:Kerberosv5ST" EncodingType="wsse:Base64Binary"> U87GGH91TT ... </wsse:BinarySecurityToken> </wsse:Security> X.509 Certificates You can also provide authentication by sending an X.509 certificate as an authentication token. <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext"> <wsse:BinarySecurityToken ValueType="wsse:X509v3" EncodingType="wsse:Base64Binary"> Hg6GHjis1 ... </wsse:BinarySecurityToken> </wsse:Security> For more information about the above approaches, see the samples that ship with WSE. Application Level Authentication You can design and build your own custom authentication by using custom SOAP headers for your application. Before doing so, review the features provided by the platform and WSE to see if any of these features can be used. If you must use a custom authentication mechanism, and you need to use cryptography, then use standard encryption algorithms exposed by the System.Security.Cryptography namespace. Authorization After authentication, you can restrict callers to a subset of the functionality exposed by your Web service, based on the caller's identity or role membership. You can restrict access to service endpoints (at the .asmx file level), individual Web methods, or specific functionality inside Web methods. Web Service Endpoint Authorization If your Web service is configured for Integrated Windows authentication you can configure NTFS permissions on your Web service (.asmx) files to control access, based on the security context of the original caller. This authorization is performed by the ASP.NET FileAuthorizationModule and impersonation is not required. Regardless of the authentication type, you can use the ASP.NET UrlAuthorizationModule to control access to Web service (.asmx) files. You configure this by adding <allow> and <deny> elements to the <authorization> element in Machine.config or Web.config. Web Method Authorization You can use declarative principal permission demands to control access to individual Web methods based on the identity or role membership of the caller. The caller's identity and role membership is maintained by the principal object associated with the current Web request (accessed through HttpContext.User.) [PrincipalPermission(SecurityAction.Demand, Role=@"Manager")] [WebMethod] public string QueryEmployeeDetails(string empID) { } Programmatic Authorization You can use imperative permission checks or explicit role checks by calling IPrincipal.IsInRole inside your Web methods for fine-grained authorization logic as follows. // This assumes non-Windows authentication. With Windows authentication // cast the User object to a WindowsPrincipal and use Windows groups as // role names GenericPrincipal user = User as GenericPrincipal; if (null != user) { if ( user.IsInRole(@"Manager") ) { // User is authorized to perform manager functionality } } Sensitive Data The threats of network eavesdropping or information disclosure at intermediate application nodes must be addressed if your Web service request or response messages convey sensitive application data, for example, credit card numbers, employee details, and so on. In a closed environment where you are in control of both endpoints, you can use SSL or IPSec to provide transport layer encryption. In other environments and where messages are routed through intermediate application modes, a message level solution is required. The WS-Security standard defines a confidentiality service based on the World Wide Web Consortium (W3C) XML Encryption standard that allows you to encrypt some or all of a SOAP message before it is transmitted. XML Encryption You can encrypt all or part of a SOAP message in three different ways: Asymmetric encryption using X.509 certificates Symmetric encryption using shared keys Symmetric encryption using custom binary tokens Asymmetric Encryption Using X.509 Certificates With this approach, the consumer uses the public key portion of an X.509 certificate to encrypt the SOAP message. This can only be decrypted by the service that owns the corresponding private key. The Web service must be able to access the associated private key. By default, WSE searches for X.509 certificates in the local machine store. You can use the <x509> configuration element in Web.config to set the store location to the current user store as follows. <configuration> <microsoft.web.services> <security> <x509 storeLocation="CurrentUser" /> </security> </microsoft.web.services> </configuration> If you use the user store, the user profile of the Web service's process account must be loaded. If you run your Web service using the default ASPNET least privileged local account, version 1.1 of the .NET Framework loads the user profile for this account, which makes the user key store accessible. For Web services built using version 1.0 of the .NET Framework, the ASPNET user profile is not loaded. In this scenario, you have two options. Run your Web service using a custom least privileged account with which you have previously interactively logged on to the Web server to create a user profile. Store the key in the local machine store and grant access to your Web service process account. On Windows 2000, this is the ASPNET account by default. On Windows Server 2003, it is the Network Service account by default. To grant access, use Windows Explorer to configure an ACL on the following folder that grants full control to the Web service process account. \Documents and Settings\All Users\Application Data\ Microsoft\Crypto\RSA\MachineKeys Symmetric Encryption Using Shared Keys With symmetric encryption, the Web service and its consumer share a secret key to encrypt and decrypt the SOAP message. This encryption is faster than asymmetric encryption although the consumer and the service provider must use some out-of-band mechanism to share the key. For more information, see the "Encrypting a SOAP Message Using a Shared Key" and "Decrypting a SOAP Message Using a Shared Key" sections in the WSE documentation. Symmetric Encryption Using Custom Binary Tokens You can also use WSE to define a custom binary token to encapsulate the custom security credentials used to encrypt and decrypt messages. Your code needs two classes. The sender class must be derived from the BinarySecurityToken class to encapsulate the custom security credentials and encrypt the message. The recipient class must be derived from DecryptionkeyProvider class to retrieve the key and decrypt the message. Encrypting Parts of a Message By default, WSE encrypts the entire SOAP body and none of the SOAP header information. However, you can also use WSE to programmatically encrypt and decrypt portions of a message. Parameter Manipulation Parameter manipulation in relation to Web services refers to the threat of an attacker altering the message payload in some way while the message request or response is in transit between the consumer and service. To address this threat, you can digitally sign a SOAP message to allow the message recipient to cryptographically verify that the message has not been altered since it was signed. For more information, see the "Digitally Signing a SOAP Message" section in the WSE documentation. Exception Management Exception details returned to the consumer should only contain minimal levels of information and not expose any internal implementation details. For example, consider the following system exception that has been allowed to propagate to the consumer. System.Exception: User not in managers role at EmployeeService.employee.GiveBonus(Int32 empID, Int32 percentage) in c:\inetpub\wwwroot\employeesystem\employee.asmx.cs:line 207 The exception details shown above reveal directory structure and other details to the service consumer. This information can be used by a malicious user to footprint the virtual directory path and can assist with further attacks. Web Services can throw three types of exceptions: SoapException objects. These can be generated by the CLR or by your Web method implementation code. SoapHeaderException objects These are generated automatically when the consumer sends a SOAP request that the service fails to process correctly. Exception objects A Web service can throw a custom exception type that derives from System.Exception. The precise exception type is specific to the error condition. For example, it might be one of the standard .NET Framework exception types such as DivideByZeroException, or ArgumentOutOfRangeException and so on. Regardless of the exception type, the exception details are propagated to the client using the standard SOAP <Fault> element. Clients and Web services built with ASP.NET do not parse the <Fault> element directly but instead deal consistently with SoapException objects. This allows the client to set up try blocks that catch SoapException objects. Note If you throw a SoapException from a custom HTTP module, it is not automatically serialized as a SOAP <Fault>. In this case, you have to create the SOAP <Fault> manually. Using SoapExceptions The following code shows a simple WebMethod, where the validation of application logic fails and, as a result, an exception is generated. The error information sent to the client is minimal. In this sample, the client is provided with a help desk reference that can be used to call support. At the Web server, a detailed error description for the help desk reference is logged to aid problem diagnosis. using System.Xml; using System.Security.Principal; [WebMethod] public void GiveBonus(int empID, int percentage) { // Only managers can give bonuses // This example uses Windows authentication WindowsPrincipal wp = (HttpContext.Current.User as WindowsPrincipal); if( wp.IsInRole(@"Domain\Managers")) { // User is authorized to give bonus . . . } else { // Log error details on the server. For example: // "DOMAIN\Bob tried to give bonus to Employee Id 345667; // Access denied because DOMAIN\Bob is not a manager." // Note: User name is available from wp.Identity.Name // Return minimal error information to client using a SoapException XmlDocument doc = new XmlDocument(); XmlNode detail = doc.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name, SoapException.DetailElementName.Namespace); // This is the detail part of the exception detail.InnerText = "User not authorized to perform requested operation"; throw new SoapException("Message string from your Web service", SoapException.ServerFaultCode, Context.Request.Url.AbsoluteUri, detail, null ); } } The consumer code that handles potential SoapExceptions follows: try { EmployeeService service = new EmployeeService(); Service.GiveBonus(empID,percentage); } catch (System.Web.Services.Protocols.SoapException se) { // Extract custom message from se.Detail.InnerText Console.WriteLine("Server threw a soap exception" + se.Detail.InnerText ); } Application Level Error Handling in Global.asax ASP.NET Web applications commonly handle application level exceptions that are allowed to propagate beyond a method boundary in the Application_Error event handler in Global.asax. This feature is not available to Web services, because the Web service's HttpHandler captures the exception before it reaches other handlers. Auditing and Logging With a Web service, you can audit and log activity details and transactions either by using platform-level features or by using custom code in your Web method implementations. You can develop code that uses the System.Diagnostics.EventLog class to log actions to the Windows event log. The permission requirements and techniques for using this class from a Web service are the same as for a Web application. Proxy Considerations If you use WSDL to automatically generate a proxy class to communicate with a Web service, you should verify the generated code and service endpoints to ensure that you communicate with the desired Web service and not a spoofed service. If the WSDL files on a remote server are inadequately secured, it is possible for a malicious user to tamper with the files and change endpoint addresses, which can impact the proxy code that you generate. Specifically, examine the <soap:address> element in the .wsdl file and verify that it points to the expected location. If you use Visual Studio .NET to add a Web reference by using the Add Web Reference dialog box, scroll down and check the service endpoints. Finally, whether you use Visual Studio.NET to add a Web reference or manually generate the proxy code using Wsdl.exe, closely inspect the proxy code and look for any suspicious code. Note You can set the URL Behavior property of the Web service proxy to Dynamic, which allows you to specify endpoint addresses in Web.config. Code Access Security Considerations Code access security can limit the resources that can be accessed and the operations that can be performed by your Web service code. An ASP.NET Web service is subject to ASP.NET code access security policy, configured by the Web service's <trust> element. .NET Framework consumer code that calls a Web service must be granted the WebPermission by code access security policy. The precise state of the WebPermission determines the range of Web services that can be called. For example, it can constrain your code so that it can only call local Web services or services on a specified server. If the consumer code has full trust, it is granted the unrestricted WebPermission which allows it to call any Web service. Partial trust consumer code is subject to the following limitations: If you call a Web service from a Medium trust Web application, by default you can only access local Web services. Consumer code that uses the WSE classes must be granted full trust. For example, if your Web service proxy classes derive from Microsoft.Web.Services.WebServicesClientProtocol, which is provided by the WSE, full trust is required. To use WSE from a partial trust Web application, you must sandbox calls to the Web service. Deployment Considerations The range of security options available to you depends greatly on the specific deployment scenarios your Web services attempt to cover. If you build applications that consume Web services in an intranet, then you have the widest range of security options and techniques at your disposal. If, however, your Web service is publicly accessible over the Internet, your options are far more limited. This section describes the implications of different deployment scenarios on the applicability of the approaches to securing Web services discussed previously in this module. Intranet Deployment Because you control the consumer application, the service, and the platform, intranets usually provide the widest range of available options for securing Web services. With an intranet scenario, you can usually choose from the full range of authentication and secure communication options. For example, you might decide to use Windows authentication if the consumer and service are in the same or trusting domains. You can specify that client application developers set the credentials property on the client proxy to flow the user's Windows credentials to the Web service. Intranet communication is often over a private network, with some degree of security. If this is insufficient, you might decide to encrypt traffic by using SSL. You can also use message level security and install WSE on both the client and server to handle security at both ends transparently to the application. WSE supports authentication, digital signatures, and encryption. Extranet Deployment In an extranet scenario, you may need to expose your Web service over the Internet to a limited number of partners. The user community is still known, predictable, and possibly uses managed client applications, although they come from separate, independent environments. In this situation, you need an authentication mechanism that is suitable for both parties and does not rely on trusted domains. You can use Basic authentication if you make account information available to both parties. If you use Basic authentication, make sure that you secure the credentials by using SSL. Note SSL only protects credentials over the network. It does not protect them in situations where a malicious user successfully installs a proxy tool (such as sslproxy) local to the client machine to intercept the call before forwarding it to the Web service over SSL. As an alternate option for use with an extranet, you can use IIS client certificate authentication instead of passing explicit credentials. In this case, the calling application must present a valid certificate with the call. The Web service uses the certificate to authenticate the caller and authorize the operation. Internet Deployment If you expose your Web service to a large number of Internet consumers and require authentication, the options available to you are substantially constrained. Any form of platform level authentication is unlikely to be suitable, since the consumers will not have proper domain accounts to which they can map their credentials. The use of IIS client certificate authentication and the transport (SSL) level is also problematic when a large number of client certificates must be made known to the target IIS Web server (or the ISA Server in front of it). This leaves message and application-level authentication and authorization the most likely choice. Credentials passed by the consumer of the service in the form of user name, password, certificate, Kerberos ticket, or custom token) can be validated transparently by the Web services infrastructure (WSE) or programmatically inside the target service. client certificates are difficult to manage scale. Key management (issuing and revoking) becomes an issue. Also, certificate-based authentication is resource intensive and therefore is subject to scalability issues with large number of clients. SSL usually provides encryption of the network traffic (server-side certificate only), but can also be supplemented by message-level encryption. Using client certificates, while advantageous from a security point of view, often becomes problematic for large numbers of users. You must carefully manage the certificates and consider how they should be delivered to clients, renewed, revoked, and so on. Another potential issue in Internet situations Is the overall scalability of the solution due to processing overhead or the encryption/decryption and certificate validation for a large-scale Web service with significant workload. Summary WS-Security is the emerging standard for Web services security. The specification defines options for authentication by passing security tokens in a standard way using SOAP headers. Tokens can include user name and password credentials, Kerberos tickets, X.509 certificates, or custom tokens. WS-Security also addresses message privacy and integrity issues. You can encrypt whole or partial messages to provide privacy, and digitally sign them to provide integrity.