How to: Use Certificate Authentication and Transport Security in WCF Calling from Windows Forms

patterns & practices Developer Center

Applies to

  • Microsoft Windows Communication Foundation (WCF) 3.5
  • Microsoft Visual Studio 2008

Summary

This how-to article walks you through the process of using client certificates to authenticate your users with transport security. First, you will learn how to create and install a client certificate for authentication and a service certificate for transport security, during development. You will then learn how to configure a binding that implements IMetadataExchange in a WCF service, and how to create a svcutil.exe.config file to allow proxy creation from the client, which is necessary when implementing transport security and certificate authentication when a WCF service is hosted in Internet Information Services (IIS). Finally, you will learn how to correctly configure security settings in IIS, and how to test the service with a sample WCF client.

Contents

  • Objectives
  • Overview
  • Summary of Steps
  • Step 1: Create and Install a Temporary Certificate for Transport Security
  • Step 2: Create and Install a Temporary Client Certificate for Certificate Authentication
  • Step 3: Create a Sample WCF Service
  • Step 4: Configure wsHttpBinding with Certificate Authentication and Transport Security
  • Step 5: Configure the mex Endpoint to Use wsHttpbinding with Certificate Authentication Configuration
  • Step 6: Configure the Virtual Directory to Use SSL and Require Client Certificates
  • Step 7: Create a Test Client
  • Step 8: Create a Svcutil Configuration File in the Client Machine
  • Step 9: Create a Proxy with the svcutil.exe Tool
  • Step 10: Test the Client and WCF Service
  • Additional Resources

Objectives

  • Learn how to create and use a temporary certificate for authentication and transport security.
  • Learn where to store the temporary certificate.
  • Learn how to configure a custom binding that implements IMetadataExchange in a WCF service to allow publishing of metadata with certificate authentication and transport security.
  • Learn how to configure a svcutil.exe.config file to be able to create a proxy to the WCF service with transport security and certificate authentication.

Overview

When developing a WCF service that uses X.509 certificates to provide client authentication and transport security, it is necessary to work with temporary certificates. This is because production certificates are expensive and may not be readily available. There are two options for specifying trust on a certificate:

  • Peer trust validates the certificate directly.
  • Chain trust validates the certificate against the issuer of a certificate known as a root authority.

Additionally, a certificate revocation list (CRL) validation is performed during certificate authentication. This validation checks the list of certificates that were revoked by the root certificate. Three modes of revocation exist:

  • Online. The CRL list is retrieved and checked online, requiring connectivity to the computer that contains the CRL.
  • Offline. The CRL list is retrieved and checked online and is then cached offline for subsequent validation.
  • NoCheck. No validation is performed.

For the purposes of this how-to article, the CRL is checked without configuration changes when using certificate authentication. The article also allows for chain trust validation when using transport security.

To use chain trust validation during development time, you first create a self-signed root certificate authority (CA) and install it in the Trusted Root Certification Authority in the Local Machine. The certificate used by WCF is then created and signed by the root self-signed certificate and installed in the Personal store of the computer account. To allow the CRL validation to succeed, you create a self-signed root CRL file and install it in the Trusted Root Certification Authority store of the Local Machine.

You will use makecert.exe to create a private key file and a certificate to act as your root CA. You will then create a CRL file from the private key that will act as your revocation list file for the root CA. You will have to install the root certificate and CRL file. Finally, you will create and install the temporary certificate from the root certificate, using the private key to sign and generate the key.

Summary of Steps

  • Step 1: Create and Install a Temporary Certificate for Transport Security
  • Step 2: Create and Install a Temporary Client Certificate for Certificate Authentication
  • Step 3: Create a Sample WCF Service
  • Step 4: Configure wsHttpBinding with Certificate Authentication and Transport Security
  • Step 5: Configure the mex Endpoint to Use wsHttpbinding with Certificate Authentication Configuration
  • Step 6: Configure the Virtual Directory to Use SSL and Require Client Certificates
  • Step 7: Create a Test Client
  • Step 8: Create a Svcutil Configuration File in the Client Machine
  • Step 9: Create a Proxy with the svcutil.exe Tool
  • Step 10: Test the Client and WCF Service

Step 1: Create and Install a Temporary Certificate for Transport Security

In this step, you create and install a temporary certificate for transport security on the server. You are also required to install the root CA on the client for trust chain validation to succeed when browsing the service in Microsoft Internet Explorer, creating the proxy to the service, and calling the service from the proxy. For a complete set of steps for creating certificates for transport security, refer to the document “How to: Create and Install Temporary Certificates in WCF for Transport Security During Development.”

Step 2: Create and Install a Temporary Client Certificate for Certificate Authentication

In this step, you create and install a temporary client certificate for certificate authentication on the client. You are also required to install the root CA and the CRL on the server in order for trust chain and revocation validation to succeed. For a complete set of steps for creating certificates for certificate authentication, refer to the document “How To: Create and Install Temporary Client Certificates in WCF for Certificate Authentication During Development.”

Step 3: Create a Sample WCF Service

In this step, you create a WCF service in Visual Studio.

  1. In Visual Studio, on the File menu, click New Web Site.

  2. In the Templates section, select WCF Service. Make sure that the Location is set to Http and specify the virtual directory to be created in the Path with https (e.g., https://ServerName/WCFTestService).

    Note that the server name needs to match the certificate name, either by NetBIOS or Domain Name System (DNS) name.

  3. In the New Web Site dialog box, click OK to create a virtual directory and a sample WCF service.

Step 4: Configure wsHttpBinding with Certificate Authentication and Transport Security

In this step, you configure the WCF service to use certificate authentication and transport security.

  1. Right-click the Web.config file of the WCF service and then click Edit WCF Configuration.

  2. In the Configuration Editor, in the Configuration section, expand Service and then expand Endpoints.

  3. Select the first node [Empty Name] and set the Name attribute to wsHttpEndpoint.

    By default, the name will be empty because it is an optional attribute.

  4. Click the Identity tab and then delete the DNS attribute value.

  5. In the Configuration Editor, select the Bindings folder.

  6. In the Bindings section, choose New Binding Configuration.

  7. In the Create a New Binding dialog box, select wsHttpBinding.

  8. Click OK.

  9. Set the Name of the binding configuration to some logical and recognizable name; for example, wsHttpEndpointBinding.

  10. Click the Security tab.

  11. Make sure that the Mode attribute is set to Transport.

  12. Set the TransportClientCredentialType to Certificate by selecting this option from the drop-down list.

  13. In the Configuration section, select the wsHttpEndpoint node.

  14. Set the BindingConfiguration attribute to wsHttpEndpointBinding by selecting this option from the drop-down list.

    This associates the binding configuration setting with the binding.

  15. In the Configuration Editor, on the File menu, select Save.

  16. In Visual Studio, open your configuration and comment out the identity element. It should look as follows:

          <!--<identity>
            <dns value="" />
          </identity>-->
    
  17. In Visual Studio, verify your configuration. The configuration should look as follows:

    …
    <system.serviceModel>
    <bindings>
        <wsHttpBinding>
          <binding name="wsHttpEndpointBinding">
            <security mode="Transport">
              <transport clientCredentialType="Certificate" />
            </security>
          </binding>
        </wsHttpBinding>
      </bindings>
    <client/>
    <services>
        <service behaviorConfiguration="ServiceBehavior" name="MyService">
          <endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"
            name="wsHttpEndpoint" contract="IService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>  
      </service>
      </services>
    …
    

Step 5: Configure the mex Endpoint to Use wsHttpbinding with Certificate Authentication Configuration

In this step, you change the configuration of the metadata exchange (mex) endpoint from mexHttpBinding (the default) to use wsHttpbinding with the configuration you created in the previous step in order to use certificate authentication. mexHttpEndpoint cannot be used for certificate authentication because the Web site requires Secure Sockets Layer (SSL), and mexHttpsEndpoint also cannot be used because it does not support certificate authentication configuration in IIS. To create a proxy to a WCF service hosted in IIS with a certificate authentication schema, you need an endpoint that implements IMetadataExchange with wsHttpbinding, with a security configuration that allows certificate authentication.

  1. In the Configuration Editor, in the Configuration section, expand Service and then expand Endpoints.

  2. Select the second node [Empty Name] and set the Name attribute to mexEndpoint.

    By default, the name will be empty because it is an optional attribute.

  3. Click the Binding attribute and change it to wsHttpbinding by selecting this option from the drop-down list.

  4. Click the BindingConfiguration attribute and change it to wsHttpEndpointBinding by selecting this option from the drop-down list.

    This associates the mex endpoint with the binding configuration setting that configures certificate authentication.

  5. In the Configuration Editor, on the File menu, click Save.

  6. In Visual Studio, verify your configuration. The configuration should look as follows. Notice that that the endpoint is now a wsHttpbinding endpoint that implements IMedataExchange (shown in bold).

    …
    <bindings>
        <wsHttpBinding>
          <binding name="wsHttpEndpointBinding">
            <security mode="Transport">
              <transport clientCredentialType="Certificate" />
            </security>
          </binding>
        </wsHttpBinding>
      </bindings>
    <client/>
    <services>
        <service behaviorConfiguration="returnFaults" name="MyService">
          <endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"
            name="wsHttpEndpoint" contract="IService" />
    <endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"
            name="mexEndpoint" contract="IMetadataExchange" />
        </service>
      </services>
    …
    

Step 6: Configure the Virtual Directory to Use SSL and Require Client Certificates

In this step, you configure the virtual directory in IIS to use SSL encryption and to require client certificates.

  1. Click Start and then click Run.

  2. In the Run dialog box, type inetmgr and then click OK.

  3. In the Internet Information Services (IIS) Manager dialog box, expand the (local computer) node, and then expand the Web Sites node.

  4. Expand Default Web Site and then right-click the virtual directory.

  5. In the Virtual Directory Properties dialog box, click the Directory Security tab, and then click editon secure communications. Click Require Secure Channel(SSL) and then click Require Client Certificates.

    You can now browse the service using Internet Explorer by navigating to https://ServerName/WCFTestService. Internet Explorer will prompt you to choose a certificate from a list of certificates installed in the user and personal stores.

Step 7: Create a Test Client

In this step, you create a Windows Forms application to test the WCF service.

  1. Right-click your solution, click Add, and then click New Project.
  2. In the Add New Project dialog box, in the Templates section, select Windows Forms Application.
  3. In the Name field, type Test Client and then click OK.

Step 8: Create a Svcutil Configuration File in the Client Machine

In this step, you create the svcutil.exe.config file that you need in order to create a proxy to the service.

  1. Right-click the project in Visual Studio, click Add, and then click New item. Select text file and name the file svcutil.exe.config.

  2. Copy the configuration file below, paste it into the svcutil.exe.config file, click File, and then click Save.

    Verify the following in your configuration file:

    1. The client certificate name is correctly specified. The certificate name is determined by the attribute findValue “CN=…” under the client credentials node.
    2. The client certificate location is correctly specified. The certificate location is determined by the attributes storeLocation="CurrentUser” storeName="My". CurrentUser and My represent the current user and personal store. This is the default location of the client certificate as specified in Step 2 above.

Step 9: Create a Proxy with the svcutil.exe Tool

In this step, you create a proxy to the service by using the svcutil.exe tool and the svcutil.exe.config file.

  1. Copy svcutil.exe from C:\Program Files\Microsoft Visual Studio 8\Common7\IDE to the same location as the svcutil.exe.config file created in previous step.

  2. Open a command prompt, navigate to the same directory as the svcutil.exe.config file, and run the following command:

    .\svcutil https://ServerName/WCFTestService /config:app.config. 
    

    This will generate two files: MyService.cs and app.config.

  3. In Visual Studio, right-click the project, click Add, and then click Existing item.

    The location defaults to the same directory as the app.config file created in the previous step.

  4. Press the CTRL key and then select the app.config and MyService.cs files.

  5. Right-click the app.config file of the WCF service and then click Edit WCF Configuration.

  6. In the Configuration Editor, in the Configuration section, expand Advanced, click Endpoint Behaviors, and then click New Endpoint Behavior.

  7. In the Name text box, type ClientEndPointBehavior and then select client credentials.

  8. Double-click clientCredentials, expand clientCredentials, and then click client certificates.

  9. In the client certificates, click findValue, enter the name of the certificate, click the store location and store name, and then select the correct values for your certificate.

    These values should be the same as in the svc.util.exe.config file.

  10. Under Endpoints, click wsHttpEndpoint B, select BehaviorConfiguration, and then select ClientEndPointBehavior.

Step 10: Test the Client and WCF Service

In this step, you access the WCF service, pass the user credentials, and make sure that the username authentication works.

  1. In your client project, drag a button control onto your form.

  2. Double-click the button control to show the underlying code.

  3. Create an instance of the proxy and call the GetData operation of your WCF service. The code should look as follows:

    private void button1_Click(object sender, EventArgs e)
    {
          ServiceClient proxy = new ServiceClient();
          MessageBox.Show(myService.GetData(123));
          myService.Close();
    }
    
  4. Right-click the client project and then click Set as Startup Project.

  5. Run the client application by pressing F5 or CTRL+F5.

    When you click the button on the form, the message “You entered: 123” should appear.

Additional Resources