WCF

The Ambient Context Design Pattern in .NET

For a piece of agent related work I’m doing at the moment I am making heavy use of multi-threaded development. I’m developing a little special purpose Agent Framework to manage some data that I maintain. As part of that work, I need to have an ambient context object to hold details about the currently active agent and the tasks that it is performing. This is a common pattern that we see used throughout the .NET framework. They’re a powerful mechanism to keep useful data around, to define scopes and to provide cross-cutting capabilities. They provide functionality and a non-intrusive management mechanism without having to clutter the components that need them with additional parameters or static variables. In effect they are a form of controlled global variable that exists to maintain scoped information.

Since I haven’t seen this pattern documented in any detail elsewhere, I thought I might make a first attempt to describe it in pattern language terms. in what follows, I’ll try to stick to the Gang of Four (GoF94) format wherever possible, but I may make a few digressions for the sake of drawing parallels with comparable facilities in the framework (.NET 3.5). I’ll also highlight when one of the characteristics I describe is not a universal feature of a context class, but is commonly enough used to be worth a mention.

(more…)

Securing a WCF service with Certificates

For a client and server to talk securely with message level encryption, they both require certificates to encrypt and decrypt messages from the other. Those certificates need to be produced and installed on each machine. This post shows how that can be done, and what settings are required to work with the certificates. Thanks to Mitch Denny, who wrote a very good post on the use of certificates, which helped a lot more than some of the official documentation. This post assumes that you’re using Juval Lowy of IDesign’s ServiceModelEx extensions for WCF. If you’re not, you should really consider these additions – they add declarative security and better validation amongst many other enhancements.

First you need to create a certificate for both the client and the server. Most examples demonstrate the scenario on a single machine thus glossing over the fact that in that situation you only need the one certificate. It obscures the real process of certificate exchange which I’ll show here.

The following is a little script (called setupcert.cmd) that will create a new certificate using makecert.exe, will add it to the ‘My’ cert store on the location machine hive of the registry. It will then export that cert for use on the other machine.

set CERT_NAME=%1
certmgr.exe -del -r LocalMachine -s My -c -n %CERT_NAME%
makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%CERT_NAME% -sky exchange -pe
certmgr.exe /put /c /r LocalMachine /n %CERT_NAME% /s my %CERT_NAME%.publickey.cer

You pass one parameter to the script, which is the common name you want to give to the certificate. For instance, you could call it “ServerSide” or “ClientSide”.

Run the script on the client side.

setupcert ClientSide

You should now have a file in the current directory called ClientSide.publickey.cer. Copy this file over to the server side. You are now be able to install the client side cert on the server side.

Double click on the client side cert file. You should get a warning about the unknown provenance of the cert.

image

Click the Open button. Then click on the ‘Install Certificate…’ button.

image

You should now be running the certificate install wizard (or equivalent).

image

Click Next. On the next page select to place the certificate in the store of your choice. A dialog box appears with the cert stores available. Check the ‘Show Physical Stores’ checkbox like so. Click OK to proceed.

image

You will now get the confirmation window.

image

Click Finish to complete the import. If all goes well you get this.

image 

At this stage we have a certificate installed on the client side called ClientSide. This certificate was copied to the server side and installed in the LocalMachine trusted people store. Now the reverse has to be done. Go to the server side and invoke the script from there.

setupcert ServerSide

copy ServerSide.publickey.cer to the client side, and from there you should repeat the import procedure outlined above. The certificates should now be configured. To confirm that, open mmc.exe and add a certificates snap-in for the local machine. On the client side you should see the ClientSide certificate in the personal certificates store.

image

In the Trusted People certificates you should see the server side certificate.

image

The reverse should be true for the Server side certificate stores.

Configuring the service endpoints

The client side proxy needs to reference its certificate like so.

ServiceProxy proxy = new ServiceProxy();
SecurityHelper.SecureProxy<IMyService>(proxy, "ClientSide");

And it can reference the server side certificate via the configuration settings.

        <endpoint 
          address="http://nitrogen:8001/MyService" 
          binding="wsHttpBinding" 
          contract="SandlNtSvc.IMyService">
          <identity>
            <dns value="ServerSide" />
          </identity>
        </endpoint>

The server side references its certificate via its security behavior attribute.

    [SecurityBehavior(ServiceSecurity.Anonymous, "ServerSide")] 
    public class MyService : IMyService
    {

That’s all the configuration needed for the service and proxy to talk to each other.

PS. remember to delete any cert files left lying around!