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