DevX HomePage

Windows Communication Foundation: The Security Model

Securing communications has never been easier. See how to set up the Windows Communication Foundation (WCF) on your system, and use configuration-based security to add or change the security requirements for your applications.
n today's world, if you cannot communicate securely using technology you may as well not communicate at all. There are countless ways that information can be taken and misused by others to the detriment of you and your business. For these reasons, Windows Communication Foundation has security at its heart, and offers many options for securing your communications to ensure that they reach their destination intact and untouched.

Discussions of security include many terms, so for the sake of clarity I want to introduce them quickly here, and map them to the real-world scenario of a person entering a country at a border crossing.

In addition to these three primary terms, there are a couple of additional communications terms that need to be clarified up front: Message Integrity and Message Confidentiality.

Now, while all this is fascinating, it's time to see what you can do with the Windows Communication Foundation so that your communiqués can be secured, have message integrity and confidentiality and use Authentication and Authorization schemes.

If you haven't done so already, now would be a good time to take a look at DevX's WCF primer, where you can get up and started with WCF.

Before you start, you should be aware that WCF is still in its beta cycle, and as such, it isn't particularly easy to get installed and running correctly. In addition, many resources you will find on the Internet (including some of them on MSDN) refer to earlier builds, so they're out of date with respect to the current model and that can lead to great confusion when you're trying to build services. In particular the web.config schema supports drastically different tags than most of those you'll find out on the net. (For example, many documentation and article pages use the tag within web.config to configure WS-Security, but that tag is now deprecated—you should use the tag instead. In addition to this, many of the child elements of the former tag have changed drastically.




Installing WCF
I have found that the best way to get up and running with WCF is to create a development system using one of the following procedures, depending on whether you have the DVD's from Microsoft's Professional Developer's Conference (PDC).

Setup Using PDC DVDs
Follow this procedure only if you're installing from the PDC DVDs.

  1. You need Windows XP SP2 or Windows Vista 5219 (Do not use Windows Vista Beta1!) Start with Disc 4 - WinFx CTP installation. This installs the WinFX runtime including WPF, WCF, and .NET Framework 2.0
  2. Move to Disc 2 - Visual Studio (Beta 2!!!). Note that there is an error with the set up—so you should copy the folder to your HD. You should also install the MSDN help, but you can install that directly from the disc.
  3. Move to Disc 5 (confused yet? You should be). This disc contains the Windows WinFX SDK in the windows SDK folder, and it installs the WinFX SDK but not the samples. It does copy the samples though, which you'll find in a .zip file called AllSamples.zip. You'll see more about this later.
  4. Now, go back to Disc 4 and install the VS Extensions for WinFx. This installs Project Templates and Item Templates for Visual Studio.
Setup Without PDC DVDs
Follow this procedure only if you're not installing from the PDC DVDs.

  1. You need Windows XP SP2 or Windows Vista 5219 (Do not use Windows Vista Beta1!)
  2. Start by downloading the WinFx CTP installation, which installs the WinFX runtime including WPF, WCF, and .NET Framework 2.0
  3. Next, get Visual Studio (Beta 2) or Visual Basic Express (Beta 2), or VC# Express (Beta 2). It supposedly doesn't matter which you use, just make sure you're using a Beta 2 version. I recommend Visual Studio, as that is what I used, and I cannot vouch for the others.
  4. Next, you need to install the Windows WinFX SDK, which installs the WinFX SDK itself, but not the samples. It does copy the samples though, which you'll find in a .zip file called AllSamples.zip. You'll see more about this later.
  5. Finally, install the VS Extensions for WinFx, which installs the Project Templates and Item Templates for Visual Studio.
After you've followed the appropriate procedure above you should be good to go in building and running WCF services. There's just one more thing that you may encounter—sometimes ASP.NET doesn't recognize WCF correctly, and your services won't run. If this happens, you should remove XWS, remove ASPNET, and then reinstall IIS, add ASPNET, and add XWS, in that sequence. So, first issue the following commands from a DOS prompt to remove XWS and ASPNET

   XWS_REG --ua
   ASPNET_REGIIS --ua
Then reinstall IIS from the Add/Remove programs control panel (remove it, then install it again), and issue these commands from a DOS prompt to add ASPNET and XWS:

   ASPNET_REGIIS --i
   XWS_REG --r --v
Finally, if you get an authentication error when trying to debug your WCF applications from Visual Studio.NET, you'll need to configure them for Integrated Windows Authentication. To do this, open the IIS manager, find the virtual directory corresponding to the service, right click it, and select Properties. In the ensuing dialog, select the directory security tab, and click the Edit button in the 'Anonymous access and authentication control' frame. In the next dialog, select 'Integrated Windows Authentication' at the bottom, click OK to close, and click OK again to close the previous dialog. You should now be good to go.




Programming Security
Developing secure applications in WCF is pretty straightforward. There are lots of methods by which you can secure an application, but this article concentrates on the WS-Security methodologies. In the WCF primer you built a simple service that provides temperature conversion from Farenheit to Centigrade and vice-versa. In this article, you'll see how simple it is to adjust that example to handle authorization and authentication credentials.

When building services for security, the key is in how you configure the web.config file at the service level. You configure security in the node, which is probably best demonstrated by an example. To configure your service to handle WSSecurity with Windows Authentication, you would have a bindings node defined like this:

   <bindings>
     <wsHttpBinding>
       <binding configurationName="Binding1">
         <security mode="Message">
           <message clientCredentialType="Windows"/>
         </security>
       </binding>
     </wsHttpBinding>
   </bindings>
Using that configuration applies the "Message" security to the binding called Binding1, using the message credential type "Windows." Therefore the user's Windows ID is passed to the service where it may be parsed to apply specific permissions. Within the service, you can use the CurrentPrincipal entity to retrieve details about the caller. For example, if you simply want the caller's name you could use code like this:

   String strName = 
      Thread.CurrentPrincipal.Identity.Name;
Although configuring security in a configuration file rather than in code may seem dangerous, it makes switching to different authentication schemes very straightforward under WCF. For example, if you wanted to use a certificate-based authentication scheme instead, you would first need a set of certificates. You can create these using the certmgr.exe utility in the following fashion from a DOS prompt or in a batch file:

To delete existing client certificates:

   certmgr -del -r CurrentUser -s My -c -n %CLIENT_NAME%
   certmgr -del -r CurrentUser -s TrustedPeople -c -n 
      %SERVER_NAME%
To delete existing server certificates:

   certmgr -del -r LocalMachine -s My -c -n %SERVER_NAME%
   certmgr -del -r LocalMachine -s TrustedPeople -c -n 
      %CLIENT_NAME%
   
To create new client certificates:

   makecert.exe -sr CurrentUser -ss MY -a sha1 -n 
      CN=%CLIENT_NAME% -sky exchange --pe
   
   certmgr.exe -add -r CurrentUser -s My -c -n 
      %CLIENT_NAME% -r LocalMachine -s TrustedPeople
   
   makecert.exe -sr LocalMachine -ss MY -a sha1 -n 
      CN=%SERVER_NAME% -sky exchange --pe
   
To copy server certificates to a client's CurrentUser store and set privileges:

   certmgr.exe -add -r LocalMachine -s My -c -n 
      %SERVER_NAME% -r CurrentUser -s TrustedPeople
   
   for /F "delims=" %%i in 
      ('"%WINFXSDK%\bin\FindPrivateKey.exe" 
      My LocalMachine -n CN^=%SERVER_NAME%   -a') 
      do 
   
         set PRIVATE_KEY_FILE=%%i
         set WP_ACCOUNT=NT AUTHORITY\NETWORK SERVICE
           (ver | findstr "5.1") && 
         Set WP_ACCOUNT=%COMPUTERNAME%\ASPNET
         echo Y|cacls.exe "%PRIVATE_KEY_FILE%" /E /G
           "%WP_ACCOUNT%":R
   
   iisreset
The preceding commands may seem like a bit of a mouthful, but you'll soon get used to them. As I mentioned earlier, the install copies, but does not install the samples; but if you unzip the AllSamples.zip file that comes with the WinFX SDK you'll find lots of samples showing how to use WCF. When a sample uses certificates, you'll find a batch file already present that executes all these commands for you. For example, check out the sample in the Basic\Binding\WSProfile\WSSecurity\Certificate subdirectory).




Configuring Security Certifactes
After you have a certificate, you can use it to authenticate yourself to the service. To set the service up to handle the certificate, configure the endpoint in web.config as follows:

   <bindings>
     <wsHttpBinding>
       <binding configurationName="Binding1">
         <security mode="Message">
           <message clientCredentialType="Certificate"/>
         </security>
       </binding>
     </wsHttpBinding>
   </bindings>
   
This probably looks familiar—and it should, because it's almost identical to the way that you set up the configuration for Windows authentication earlier. All you have to do is change the message client credential type to 'Certificate'.

To recap—each service is configured with a service description in web.config that specifies the endpoint and the behavior. The endpoint specifies the binding. The binding specifies the security type. The knee bone is connected to the thigh bone, etc.

Finally, you need to set up the binding behavior to inform the service of the certificate and how to handle it. To do that, you configure the behavior (pointed to by the service configuration) to recognize the certificate. You would do it something like this:

   <behaviors>
     <behavior configurationName=
        "TemperatureServiceBehavior"
        returnUnknownExceptionsAsFaults="true" >
       <serviceCredentials>
          <serviceCertificate findValue="localhost"  
             storeLocation="LocalMachine"
             storeName="My"    
             x509FindType="FindBySubjectName" />
       </serviceCredentials>
     </behavior>
   </behaviors>
   
As you can see, the preceding behavior is set up with service credentials configured to use a service certificate.

On the server side, pulling information out of the security context is a little different. Because this is certificate-based, you don't use the Windows Principal object—you use the ServiceSecurityContext object instead (found in the System.ServiceModel namespace, the core of WCF) like this:

   String strName = ServiceSecurityContext.Current.
      PrimaryIdentity.ToString();
Setting up your client to pass certificates to the server is also pretty straightforward. You simply generate the proxy using the svcutil tool (see the WCF primer article for more details) and consume the proxy within your client code.

Security is at the heart of the Windows Communication Foundation, which has been designed carefully to allow you to build security into your applications as unobtrusively as possible. As demonstrated in this article, you were able to build a service/client pair for Windows-based and Certificate-based WSSecurity without changing your code in any great way—the changes were all configuration driven. This is the heart of WCF; it lets you concentrate on building business logic, and then empower it for secure, reliable, and transactable connectivity in as easy a way as possible.

At this point, getting WCS up and running with a development environment is difficult, but that will improve over time. By carefully following the installation procedures and sequences described in this article, you should be able to get up and running quickly (it took me several days to set up my first system, but after working out the kinks and following the installation procedures, I got it down to a couple of hours). The best resource to work from (other than this article!) is to unzip the Allsamples.zip file that gets installed with the WinFX SDK. I recommend that you use those samples as a reference for configuring security in your WCF applications, as there are many examples, each having a configuration for each type of security methodology. Above all, have fun!

Laurence Moroney is a freelance enterprise architect who specializes in designing and implementing service-oriented applications and environments using .NET, J2EE, or (preferably) both. He has authored books on .NET and Web services security, and more than 30 professional articles. A former Wall Street architect, and security analyst, he also dabbles in journalism, reporting for professional sports. You can find his blog at http://www.philotic.com/blog.


DevX is a division of Jupitermedia Corporation
© Copyright 2007 Jupitermedia Corporation. All Rights Reserved. Legal Notices