Mike Taulty's Blog
Bits and Bytes from Microsoft UK
WSE 3.0: Playing with policy and security

Blogs

Mike Taulty's Blog

Elsewhere

With WSE you can choose to apply security to your web services through either code or configuration and most people would choose configuration. You get WS-Security provided features of authenticating who a SOAP message came from, checking the integrity of the message for tampering and also protecting the privacy of the message from people who snoop on it.

If you go down the configuration route then you apply it via policy. This means that you deploy a little XML file next to the service and the XML file controls what you are/aren't prepared to send and receive. For instance you can require that your service won't receive a message unless it's signed with a Kerberos token and so on.

You can drop a similar policy file next to a client as well and, thereby, get a client and service to have compatible policies so that they can exchange messages.

In WSE2.0 you used a configuration wizard to build the policy file specifying your requirements around authentication, integrity and privacy and it spat out a file that complied with the general WS-Policy specification and the more specialised WS-SecurityPolicy bits.

WSE2.0 didn't have any mechanism for you to communicate your policy from your service to your client (or vice versa) and that was left to some "out of band" mechanism. There are standard mechanisms for doing this (WS-PolicyAttachment and WS-MetadataExchange are two) but they weren't there in WSE2.0

The "problem" with WSE2.0 policy configuration was that it offered possibly too many options. You could go and (for instance) build a service which would do authentication by supplying a user name and password across the network with no protection which isn't likely to be a good thing.

In WSE3.0 the idea of policies seems to remain (i.e. XML configuration files dropped next to the service or the client to control how they go about sending/receiving messages) but the policy files themselves look to have been simplified. From what I can see that means that they are no longer WS-Policy/WS-SecurityPolicy compliant but the impact of that is likely to be fairly low given there was no interchange mechanism in the first place.

In WSE3.0 you I built a service like this one;

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using Microsoft.Web.Services3;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Policy("MikePolicy")]
public class Service : System.Web.Services.WebService
{
    public Service () {
    }

    [WebMethod]
    public string HelloWorld() {
        return "Hello World";
    }

}

and then used the provided Wizard in VS 2005 to build the policy file which looks like the one below in order to have my service require that the client provides a user name and password to authenticate itself and that it signs and encrypts all the important bits of the message using an X509 certificate (which the client would need to have the public key for).

<policies>
    <extensions>
        <extension name="usernameOverCertificateSecurity" type="Microsoft.Web.Services3.Design.UsernameOverCertificateAssertion.../>
        <extension name="x509" type="Microsoft.Web.Services3.Design.X509TokenProvider.../>
    <policy name="MikePolicy">
        <usernameOverCertificateSecurity .../>
            <serviceToken>
                <x509 storeLocation="CurrentUser" .../>

            </serviceToken>
        <protection>
            <request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />
            <response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />
            <fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
        </protection>
        </usernameOverCertificateSecurity>
    </policy>
</policies>

I missed some bits out up there just to shorten it down. To do a similar thing on the client side you set up your policy again and on the proxy that gets generated you do;

MyProxy p = new MyProxy();

p.SetPolicy("MikePolicy");

to have the client pick up the policy and make use of it.

The items that you list in the extensions section of the policy file look to be classes that ultimately derive from PolicyAssertion in the framework. PolicyAssertion's role in life seems to be to create input and/or output filters on both the "client" and "service" side and those filters get slotted into the WSE pipeline to pre- and post-process messages as they go in/out of services and clients.

An extension also gets handed a lump of configuration file so that it can set itself up (as we can see with usernameOverCertificateSecurity above). The overrides you have to write for a PolicyAssertion look like;

public override SoapFilter CreateClientInputFilter(FilterCreationContext context)
public override SoapFilter CreateClientOutputFilter(FilterCreationContext context)
public override SoapFilter CreateServiceInputFilter(FilterCreationContext context)
public override SoapFilter CreateServiceOutputFilter(FilterCreationContext context)
public override void ReadXml(System.Xml.XmlReader reader, System.Collections.Generic.IDictionary<string, Type> extensions)
public override void WriteXml(System.Xml.XmlWriter writer)

The list of pre-canned security assertions that you have to play with looks to be;

  • usernameOverCertificateSecurity
  • usernameOverTransportSecurity
  • mutualCertificateSecurity
  • anonymousOverCertificateSecurity
  • kerberosSecurity

There might be a couple more - not gone all the way through this yet. So far, I've experimented only with usernameOverCertificateSecurity. Will update this post or add a new one at the point where I've played with the others.


Posted Mon, Jun 27 2005 8:09 AM by mtaulty