Policy Support in WSE


Version 2.0 of WSE includes the ability to declare and enforce WS-Policy “ based restrictions on Web services that are enabled to use WSE. While WS- Policy implies that policy is something that applies only to inbound messages, WSE has been designed to apply WS-Policy functionality to outbound messages as well. This enables you to place the same type of policy restrictions on outbound messages to ensure that they will conform to the receivers published policy. And even better, WSE will attempt to automatically retrieve the necessary security tokens and do the work of signing and encrypting the message to bring it into compliance to the outbound policy. This means that a well planned use of policy with WSE can greatly reduce the amount of code that you need to write, and by using policy, you can change security requirements for your WSE-based application on the fly without having to modify and recompile your code.

In both inbound and outbound cases, policy enforcement is implemented by a set of policy input and output filters. The policy verification input filter ensures that incoming messages conform to policy assertions registered for the requested resource. If an incoming message does not conform to these requirements, a PolicyValidationException is thrown and a message containing a Fault element in the body is returned to the sender with an error message indicating that the request did not conform to the policy. Conversely, the WSE policy- enforcement output filter also ensures that all outgoing messages conform to any send policies defined for outbound messages. If the SoapContext object of an outbound message doesn t already have the elements needed to conform to the send policy, this filter attempts to retrieve security tokens from a security token cache and sign or encrypt the message to bring it into conformance with the policy. If a send-policy violation is detected in an outbound message, a PolicyEnforcementException exception is thrown.

The policy documents used by WSE when testing messages for compliance are stored at the local computer in an XML policy cache file. While typically stored in the directory with the application, policy cache files can be stored in any directory to which the WSE runtime, under the ASP.NET worker process account, has access. The policy cache document is made up of one or more policy assertions, as specified by WS-Policy, and a mapping between policies and the resources against which the policies are being verified , wherein policies are mapped to resources using the Id policy attribute. The following is an example of a valid WSE policy cache document:

 <?xml version="1.0" encoding="utf-8"?> 
<policyDocument xmlns="http://schemas.microsoft.com/wse/2003/06/Policy">
<mappings xmlns:wse="http://schemas.microsoft.com/wse/2003/06/Policy">
<mapDefault policy="#policy-daa98f8b-4eb9-4324-a13a-a7e5293c54d8" />
</mappings>
<policies xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext/">
<wsp:Policy wsu:Id="policy-daa98f8b-4eb9-4324-a13a-a7e5293c54d8"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">
<wsp:All>
<wsse:Integrity wsp:Usage="wsp:Required" wsp:Preference="10"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:TokenInfo>
<SecurityToken
xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:TokenType>wsse:X509v3</wsse:TokenType>
<wsse:Claims>
<wsse:SubjectName>WSE Test Certificate</wsse:SubjectName>
</wsse:Claims>
</SecurityToken>
</wsse:TokenInfo>
<wsse:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()
</wsse:MessageParts>
</wsse:Integrity>
<wsse:Confidentiality wsp:Usage="wsp:Required" wsp:Preference="10"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:KeyInfo>
<SecurityToken
xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:TokenType>X509v3</wsse:TokenType>
<wsse:Claims>
<wsse:SubjectName>WSE Test Certificate</wsse:SubjectName>
</wsse:Claims>
</SecurityToken>
</wsse:KeyInfo>
<wsse:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()
</wsse:MessageParts>
</wsse:Confidentiality>
</wsp:All>
</wsp:Policy>
</policies>
</policyDocument>

Version 2.0 of WSE implements support for both Confidentiality (encryption) and Integrity (signing) assertions out of the box. To use the policy filters to validate or enforce any other policy assertions defined by WS-PolicyAssertions or WS-SecurityPolicy, you will need to use the policy API implemented in the Microsoft.Web.Services.Security.Policy and Microsoft.Web.Services.Policy namespaces to write your own assertions handler. After writing the handler, you must then register it with the policy filters. As this is an advanced scenario, I won t be covering it here. Instead, you should refer to the WSE 2.0 SDK documentation.

In theory, the WSE policy filters should be able to successfully parse any policy assertions that conform to the WS-Policy, WS-PolicyAssertions, and WS- SecurityPolicy specifications. However, to ensure that a policy cache document can be successfully parsed and interpreted by WSE, you should either use the WSE Settings Tool to create a basic policy cache document or possibly start with a WSE-generated document and add your own assertions and operators. In the next section, I will show how to use the WSE Settings Tool to generate a simple policy cache document.

In version 2.0, WSE doesn t support any of the discovery mechanisms for policies described in WS-PolicyAttachment. To make policies visible to applications that consume your Web service, you must either send a copy of a policy document to your Web service s consumers or present an accessible URL location from which the policy document can be accessed. An even better way to make policies discoverable would be to manually edit the WSDL file, following the rules prescribed in WS-PolicyAttachment that I discussed earlier. Then you must publish both the WSDL and the policy document file so that applications can access these discovery documents. When publishing a policy document, it would be nice to be able to digitally sign it, as is recommended by WS-Policy. However, in this release, WSE doesn t provide an easy way to apply the WS- Security features to a policy cache document. Remember that as it stands today, WSDL consuming tools, such as the Visual Studio .NET Add Web Reference tool, will not be about to automatically consume these policy extensions to your WSDL files and be able to find the referenced policies, although I hope that in the future they will do so.

Configuring WSE for Policies

When you re enabling WSE policy enforcement, the WSE Settings Tool can make this task much easier, and you can use this tool whether or not you ve already created a policy document. To define policies for a Web service after you have installed the WSE Settings Tool, you can right-click on the Web service in the Project Explorer pane of Visual Studio and select WSE Settings. This launches the WSE Settings Tool. Figure 6-1 shows the Policy tab of the WSE Settings Tool.

click to expand
Figure 6-1: WSE Settings Tool policy settings

Here you can specify existing policy cache documents for incoming and outgoing messages as well as define your own custom code to handle some other unsupported policy assertions. From this screen, you can click Browse and specify an existing policy cache document, or by clicking Create/Edit, you can either create a new policy cache document or modify policy assertions in an existing one. This tool also includes a policy editor utility that lets you build a simple policy statement, and you can define multiple policies for different resources on your Web server. Figure 6-2 shows the policy options supported by the user interface when you create a new policy.

click to expand
Figure 6-2: Add/Edit Policy screen

Note that in this version of WSE, you can use this tool to specify only two assertions. This tool lets you to specify the following information about a security token:

  • TokenType Policy element that specifies the type of token, which can be one of the following types, by qualified name :

    • wsse:X509v3 ” a token containing an X.509 v3 certificate

    • wsse:Kerberosv5ST ” a token containing a Kerberos V5 service ticket

    • wsse:UsernameToken ” a Username token defined in WS- Security

      Note

      While WS-SecurityPolicy defines tokens types for Kerberos ticket-granting tickets (TGT), SAML Assertions, and XrML Licenses, these tokens were not supported in the pre-beta version of WSE 2.0 on which I based this chapter.

  • TokenIssuer Policy element that specifies a required security authority that issued the token; supported for X.509 and Kerberos- based tokens. Specifying this element helps WSE more easily obtain the correct security token.

  • SubjectName Child element of the Claims policy element that is used to specify a required value of the subject string for an X.509 or Kerberos-based token or the value of Username for a Username token. Specifying this element helps WSE more easily obtain the correct security token.

  • Role WSE-specific element that extends the Claims policy element in order to require that the Kerberos-based security token maps to a member of the specified Windows group, where the group is qualified with the Windows domain as domain\ group .

  • ServiceName Child element of the Claims policy element that is defined in WS-SecurityPolicy when using Kerberos-based tokens for specifying the required PrincipalName for the service, which maps to the sname field in the Kerberos service ticket.

This information can be used by WSE to automatically find and retrieve security tokens based only on information in the policy expression and without you having to write any code. When saved to a policy cache file, the selections shown in Figure 6-2 are translated into the following XML document:

 <?xml version="1.0" encoding="utf-8"?> 
<policyDocument xmlns="http://schemas.microsoft.com/wse/2003/06/Policy">
<mappings xmlns:wse="http://schemas.microsoft.com/wse/2003/06/Policy">
<map to="http://example.com/MyWebService.asmx">
<default policy="#policy-08d5feba-1079-4e05-acb4-874bcd524d9f" />
</map>
</mappings>
<policies xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<wsp:Policy wsu:Id="policy-08d5feba-1079-4e05-acb4-874bcd524d9f"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">
<wsse:Integrity wsp:Usage="wsp:Required"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:TokenInfo>
<SecurityToken xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:TokenType>wsse:X509v3</wsse:TokenType>
<wsse:Claims>
<wsse:SubjectName>WSE Test Certificate</wsse:SubjectName>
</wsse:Claims>
</SecurityToken>
</wsse:TokenInfo>
<wsse:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()
</wsse:MessageParts>
</wsse:Integrity>
<wsse:Confidentiality wsp:Usage="wsp:Required"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:KeyInfo>
<SecurityToken xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:TokenType>wsse:X509v3</wsse:TokenType>
<wsse:Claims>
<wsse:SubjectName>WSE Test Certificate</wsse:SubjectName>
</wsse:Claims>
</SecurityToken>
</wsse:KeyInfo>
<wsse:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()
</wsse:MessageParts>
</wsse:Confidentiality>
</wsp:Policy>
</policies>
</policyDocument>

Notice that WSE generates both policy assertions in the same Policy element, and it generates a GUID for mapping the policy to the http://example.com/MyWebService.asmx Web service. While the complexity and types of assertions in a WSE-generated policy cache document are limited, this auto- generated document can provide the starting point for adding policy operators. However, if you need to implement a policy assertion not natively supported by WSE, you will still need to write your own assertion handler.

One of the main benefits of enforcing send-side policy statements on outbound messages is that WSE will automatically attempt to retrieve the required security tokens and use them to satisfy the send policy. Depending on how detailed your send policy statement is, WSE will attempt to create a security token from a source object, like an X.509 certificate or a Kerberos ticket. If this cannot be done, WSE will try to retrieve an existing token to fulfill the send policy from the security token cache.

Using the Security Token Cache

When you define a send policy that requires a security token, WSE attempts to obtain the token from a token cache, which is a memory-resident collection of security token objects that can be accessed by WSE at run time. For example, consider the following policy cache document used by WSE, which requires the outgoing message to be both encrypted and signed:

 <?xml version="1.0" encoding="utf-8"?> 
<policyDocument xmlns="http://schemas.microsoft.com/wse/2003/06/Policy">
<mappings xmlns:wse="http://schemas.microsoft.com/wse/2003/06/Policy">
<map to="http://localhost/DocumentService/DocumentService.asmx">
<default policy="#policy-a6bf6cc2-a522-4f64-bb71-7c10b1a29beb" />
</map>
</mappings>
<policies xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<wsp:Policy wsu:Id="policy-a6bf6cc2-a522-4f64-bb71-7c10b1a29beb"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">
<wsse:Integrity wsp:Usage="wsp:Required"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:TokenInfo>
<SecurityToken xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:TokenType>wsse:X509v3</wsse:TokenType>
</SecurityToken>
</wsse:TokenInfo>
<wsse:MessageParts
Dialect=http://schemas.xmlsoap.org/2002/12/wsse#part
>wsp:Body()</wsse:MessageParts>
</wsse:Integrity>
<wsse:Confidentiality wsp:Usage="wsp:Required"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:KeyInfo>
<SecurityToken xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:TokenType>wsse:X509v3</wsse:TokenType>
</SecurityToken>
</wsse:KeyInfo>
<wsse:MessageParts
Dialect=http://schemas.xmlsoap.org/2002/12/wsse#part
>wsp:Body()</wsse:MessageParts>
</wsse:Confidentiality>
</wsp:Policy>
</policies>
</policyDocument>

Using X.509 certificates, you would encrypt the response message using the security token included with the request message, which can be obtained from the SoapContext of the request message as follows :

 // Get the client provided token with which to encrypt the response 
SecurityToken myEncryptToken = null;

if (myRequest.Security.Tokens.Count > 0)
{
foreach (SecurityToken token in myRequest.Security.Tokens)
{
if (token.SupportsDataEncryption)
{
myEncryptToken = token as X509SecurityToken;
}
}
if (myEncryptToken == null)
{
throw new SoapException("The provided token cannot be used to encrypt the response",
SoapException.ServerFaultCode);
}
}

// Get the SoapContext of the outgoing message
SoapContext myResponse = ResponseSoapContext.Current;

// Encrypt the response with the clients token
myResponse.Security.Elements.Add(new EncryptedData(myEncryptToken));

Since this Web service code encrypts the message body using an X.509 certificate, the response message will satisfy the Confidentiality assertion in the send policy. However, you still need to add a signature element to satisfy the Integrity assertion. While this can easily be done programmatically, as I showed in Chapter 5, since all outgoing messages must be signed according to the send policy and the same token is used to sign each message, it makes more sense to use the global security token cache.

WSE implements a global token cache that is used with send policy enforcement, which can be accessed programmatically using a SecurityTokenCache . To ensure that the required security tokens exists in this cache when an send policy is being enforced on outbound messages, security tokens are added to the cache using the object s Add method. The following code instantiates the global cache, and when the Web service is loaded, an X.509 token is retrieved using the service s GetX509Token method and is added to the cache:

 // Set the key for the X509 signing certificate 
private static string signingKey = "1lQTOBNw/oAxtTI3iwsGJaIM1fE=";


public DocumentService()
{
//CODEGEN: This call is required by the ASP.NET Web Services Designer
InitializeComponent();

// Load the signing key into the global token cache
SecurityTokenCache.GlobalCache.Add(GetX509Token(signingKey));
}

Now, with at least one X.509 certificate in the global cache, the WSE runtime will get this token to sign the response message and fulfill the send policy. Of course, if you provide enough detail in the wsse:Claims and wsse:SubjectName children of the wsse:TokenInfo node in the send policy statement, WSE will be able to automatically retrieve the needed certificate without having to go to the token cache, and all of this information can be supplied using the WSE Settings tool.




Understanding Web Services Specifications and the WSE
Understanding Web Services Specifications and the WSE (Pro Developer)
ISBN: 0735619131
EAN: 2147483647
Year: 2006
Pages: 79

Similar book on Amazon

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