Jeannine Hall Gailey

Subscribe to Jeannine Hall Gailey: eMailAlertsEmail Alerts
Get Jeannine Hall Gailey: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Article

Advanced Web Services Policies & Microsoft WSE

Use WS-Policy support in Microsoft WSE to secure your .NET Web services

While widely adopted or standardized security protocols are great for interoperability, a set of SOAP message header elements as well as a few new elements that belong in the message body are outside the scope of the existing mechanism for publishing service descriptions, which is WSDL.

In my previous article (WSJ, Vol. 4, issue 3), I covered the basic tenets of the WS-Security (recently renamed by OASIS as SOAP Message Security). This specification leverages existing XML security functionality to enable a uniform way to implement security for SOAP messages. WS-Security implements a set of SOAP message header elements as well as a few new elements that belong in the message body. While WSDL is designed to describe components of a Web service, such as exposed Web methods, data types, ports, and SOAP message elements, it has proven less useful when it comes to describing choices, preferences, and other requirements not tied directly to the messaging interface itself. It's all well and good if our Web service rejects all incoming SOAP requests that don't contain a certain type of security token or that don't have the required signatures, but how do we communicate these requirements to clients that want to access the service? What is needed is a more comprehensive way of describing a Web service - not just the interface, but requirements and expectations as well.

Introducing WS-Policy

Enter the WS-Policy family of specifications. Proposed by IBM, BEA, SAP, Microsoft, and others, WS-Policy simply defines a framework and mechanisms for constructing policy expressions that describe the requirements for accessing a Web service. In this policy-based model for Web services, individual requirements are declared using XML policy assertion elements. An assertion might declare something like "if you send me a request, you need to digitally sign the message" or "I only accept X.509-based security tokens" or even "I only accept messages that conform to version X of a given specification." A policy expression can be comprised of one or more policy assertions assembled using logical policy operators, and this expression can also be associated with a Web service resource (such as a service or endpoint) using WSDL or other mechanisms defined in WS-PolicyAttachment.

Declaring Policy Assertions

Policy assertions are the building blocks of policies. Each assertion describes an atomic aspect of a service's requirements. WSE 2.0 supports the following policy assertions, which are defined in the WS- SecurityPolicy specification:
  • SecurityToken: Declares that a security token be contained in or referenced from the message and defines which type of security token can be used to secure a message as well as attributes of the token.
  • Integrity: Declares that one or more digital signatures are required and defines which parts of the message are signed, the signing algorithm, and information on the token used for signing.
  • Confidentiality: Declares that part of the message is encrypted and defines which message parts are encrypted, the encryption algorithm, and information on the token used for encryption.
Other policy assertions, which are used to specify encoding, language, and versioning requirements, are described in WS-PolicyAssertion.

Building Complex Policy Expressions

Consider the simple policy expression shown in Listing 1. The All element is a policy operator that defines how the policy attributes, child elements of All that can be either assertions or other operators, are applied. Since the use of All indicates that the requirements of all child elements must be met, the net result for this policy expression is that any request message must contain an X.509-based security token, a digital signature of the message created using an X.509-based token, and a body element encrypted using an X.509-based token. WS-Policy defines a set of policy operators that enables us to construct policy assertions into logical blocks to better describe complex policy requirements. These policy operators include:
  • All: Message must conform to all of the assertion and operator elements that are direct children of this element.
  • ExactlyOne: Message must conform to exactly one of the assertion or operator elements that are direct children of this element, and the assertion or operator with the highest value for the Preference attribute indicates the preferred child element.
  • OneOrMore: Message may conform to one or more of the assertion or operator elements that are direct children of this element, and the assertion or operator with the highest value for the Preference attribute indicates the preferred child element.
You can use these operators to construct policy expressions that can accurately describe the complex requirements of your Web services. For example, the policy expression in Listing 2 describes a Web service that accepts three kinds of security tokens: Username, X.509-based, and security context tokens (SCT), where use of each type of security token has a unique set of requirements. In this example, the top-level ExactlyOne operator declares that only one type of authentication be implemented in the request, and the Preference attribute is used to indicate that security context tokens are most desired (Preferrence="90") while username tokens are accepted but least desired (Preferrence="30"). Each child of ExactlyOne is treated as a logical policy block, where All child elements are used to indicate that each authentication mechanism "block" requires a security token as well as either a digital signature, encryption, or both.

While a service that accepts three types of security tokens might not be common in the real world, it does demonstrate the versatility of the policy framework.

Introducing WSE 2.0

Since I described Web Services Enhancements (WSE) version 2.0 for Microsoft .NET in my first article, I will provide only a brief recap before discussing policy support in WSE 2.0. WSE is a .NET assembly that supports both TCP and HTTP transports and implements a set of input and output filters that read incoming SOAP messages and translate known SOAP header elements into WSE programming objects. In a similar fashion, WSE output filters construct SOAP headers based on the properties of the SoapContext object for the outgoing message. WSE also implements a policy engine that parses policy cache documents to ensure that incoming and outgoing messages conform to the service's defined policy. WSE provides a rich API to enable programming WSE from your applications.

Support for Policy in WSE 2.0
While policies were initially conceived as a way to extend WSDL to better communicate the requirements for clients to successfully interact with a Web service, WSE 2.0 puts an interesting spin on this original intent. While it does not directly support the attachment of policies to WSDL (as defined in WS-PolicyAttachment), it does use policy expressions to better automate the implementation of Web service security. When you create and store one or more policy expressions in the Web service's receive-policy cache, WSE will use this policy document when it evaluates incoming request messages, rejecting all requests that do not conform to the effective policy. Similarly, WSE will consult the send-policy cache document to ensure that outgoing messages conform to it as well. The really cool thing about the send-policy cache is that WSE will attempt to automatically generate the required security headers to bring the message into conformance with the policy. This enables you to secure outbound messages based only on a well-constructed policy document and without writing a line of WSE code.

A single policy cache document can contain multiple policy expressions that each map to a unique resource hosted by the Web service. For example, you might define a default policy for your Web service and a separate policy for a security token service hosted by your service. WSE uses the Policy element's ID attribute to map a Web service resource to a specific policy. It uses the policyDocument element to denote a policy cache document. Listing 3 shows a receive-side policy cache document that contains two policy expressions, one that is mapped to default, which is used for all requests to the Web service's virtual directory, and a second mapped to http://myservice/secureConversation.ashx, which is used for specific requests to the WSE-provided security context token service. (Note: These policy expressions have been truncated for readability.) In order for WSE to know to use a given policy document as the receive-side or send-side policy cache, the web.config file for the service is modified to point to the policy documents. Listing 4 shows how the policy element in the micrsoft.web.services configuration block is used to specify send- and receive-side policy cache documents.

Defining Policies Using WSE Tools

Since WSE 2.0 supports WS-Policy, WS-PolicyAttachment, and WS-SecurityPolicy, you could manually construct a policy document based on these specifications. However, hand-coding XML can easily result in errors that will prevent WSE from loading parsing the policy document. The same applies when editing the web.config file to tell WSE to apply send- or receive-side policies. The easiest way to use policies with any WSE-enabled application is to use the WSE Settings tool, which is a Visual Studio add-in that enables you to easily configure WSE. Note that this tool is essentially the same for both client and service endpoints, except that changes are made in either web.config for an ASP.NET Web service or in app.config for a WSE-enabled client application. When defining policies, it is important that they represent the behavior of the WSE at a given endpoint. For example, don't specify the use of username tokens if you haven't written a custom username token handler, and don't specify encryption with a username token because WSE doesn't support it.

To define policies for your project:

  1. Right-click the project in the Visual Studio Solution Explorer window and select WSE Settings 2.0. This displays the WSE Settings Tool.
  2. In the General tab, check both checkboxes to enable WSE for the Web service. (When enabling WSE for a client application, the ASP.NET checkbox will be grayed out.)
  3. In the Security tab specify the security behaviors of WSE.
  4. In the TokenIssuing tab, specify if a security context token service or other custom token service is hosted by WSE (Web service endpoints only).
  5. In the Policy tab (see Figure 1), check the Enable Policy checkbox and click Add. This starts the WSE Security Settings Wizard.
  6. On the Choose the Type of Application screen of the wizard, select either a client or service application and if Secure Conversation (using SCTs) is required. When requiring Secure Conversation, incoming messages must have an SCT, be signed and encrypted.
  7. On the Message Settings page of the Wizard, select the security policy requirements for incoming and outgoing messages.
  8. On the Client Authentication Token screen of the Wizard, select the type of token (Username, Kerberos-based, or X.509-based) is required for authentication and securing messages.
  9. For a Web service and depending on the type of security token selected in Step 8, the next screen of the wizard enables you to restrict who can access the service, but this level of restriction is optional.
  10. If there are requirements for encryption on incoming messages or signatures on outgoing messages, you must specify an X.509-based certificate for this on the Server Certificate screen of the wizard (see Figure 2).
  11. Create Security Settings, the final screen of the wizard shown in Figure 3, displays a recap of the security policy settings that are created when you click OK to complete the wizard.
  12. Click OK to close the WSE Settings tool. WSE automatically modifies the appropriate configuration file for the application so that it references the newly created policy cache document.

Beyond the WSE Policy Tools

As you have seen, WSE tools are able to generate very simple policy documents, containing only one Integrity assertion and one Confidentiality assertion, and it is not even able to create an independent SecurityToken assertion. However, the policy parser implemented by the WSE runtime fully supports the WS-Policy specification. This means that WSE can handle policy expressions as complex as the one shown in Listing 2, which implements the full range of security policies as well as all of the operators defined in WS-Policy. The best way to create a policy document as complex as the one in Listing 2 is to define a policy using the WSE Setting tool to generate your assertions, which can be arranged into logical groups using the three policy operators, All, ExactlyOne, and OneOrMore - following the rules in WS-Policy.

Limitations of Policy in WSE

Since WSE 2.0 does not modify WSDL as specified in WS-PolicyAttachment, you have to communicate policies to your clients either by manually editing the WSDL document to reference the location of your Web service's policy document or by sending the policy document to the client using some other out-of-band mechanism. It would be convenient to have the Web service implement a method that returns the policy document. However, WSE must positively authenticate every request using a supplied security token, or how will a client know which tokens are accepted without access to the policy.

Conclusion

In the emerging world of well-secured Web services, WS-Policy provides a much needed mechanism for describing the security requirements for accessing Web services. While WSE 2.0 does not enable the communication of policies, it does help you to easily create policy expressions and leverages them to ensure that incoming and outgoing messages conform to these policies. One of the most useful features of WSE is the ability to use the send-side policy cache to automatically secure outgoing messages without writing a line of code. While WSE supports the policy assertions defined in WS-SecurityPolicy and the policy operators defined in WS-Policy, its tools are only able to define rudimentary polices. In future releases, I look forward to improved tool support and support for additional policy assertions out of the box.

More Stories By Jeannine Hall Gailey

Jeannine Hall Gailey is a full-time freelance writer. Previously the
manager of the .NET My Services SDK documentation project team, she
worked in technical documentation for seven years. She contributed to
Microsoft .NET My Services Specification (Microsoft Press) and is
working on another book. Visit her Web site at www.webbish6.com for
code downloads and discussions.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.