Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

 

patterns & practices Developer Center

How To: Call a Web Service Using Client Certificates from ASP.NET 1.1

J. D. Meier, Program Manager (Microsoft Corporation)
Andy Wigley, Principal Technologist (Content Master)
Leon Braginski, Technical Lead (Microsoft Corporation)

Published: May 2005

Last Revised: January 2006

Applies To

  • ASP.NET 1.1
  • Internet Information Services (IIS) 5.0 and 5.1

See the "patterns & practices Security Guidance for Applications Index" for links to additional security resources.

See the Landing Page for a starting point and complete overview of Building Secure ASP.NET Applications.

Summary

This How To describes how you can pass a client certificate to a Web service for authentication from an ASP.NET Web application or from a Windows Forms application. You can install the client certificate in either the local machine store or the user store.

If you store the client certificate in the local machine store, you must configure the Access Control List (ACL) on the certificate to allow access to your application's account. If you are running a Windows Forms application, this account is your user account. If you are running an ASP.NET application, this account is the Network Service account by default on the Microsoft® Windows Server™ 2003 operating system. If you have configured a custom account to run your ASP.NET application, you must configure the ACL to grant access to the custom account.

If you store the certificate in an account's user store, applications that run using that account identity can access the certificate from there.

Contents

Local Machine Store
User Store
Calling the Web Service
Web Services Enhancements 2.0
Internet Information Server 5.0 or 5.1

Overview

Web services often need to be able to authenticate their callers (other applications). One authentication technique is to require callers of the Web service to present a client certificate.

There are two common situations where client certificates are used:

  • An ASP.NET Web application calls a Web service that uses certificate authentication.
  • An application running under interactive user context, such as a Windows Forms application, calls a Web service that uses certificate authentication.

The code that makes the Web service call is the same in both of these scenarios, although the way you install the certificate on the client computer may differ. You can install a client certificate in one of two certificate stores:

  • The local machine store
  • The user store

When a user installs the client certificate to access a particular Web service, by default this certificate is installed in that user's store. If that user runs a Windows Forms application that accesses the Web service, the application uses the certificate from the user's store. However, if the same user runs a Web application that tries to call the Web service, the Web application fails. This is because by default, ASP.NET applications do not run using the calling user's identity and so cannot access certificates in a user's store. The usual solution is to install the certificate in the local machine store so that the account used to run ASP.NET can access it.

If you store a certificate in the local machine store, you need to configure its ACL to grant access to your application's account, such as the Network Service account. This is the default account used to run Web applications on Windows Server 2003.

If you host multiple applications on the same server and want to restrict certificate access to a specific application, you need to run your application using a custom account and grant access only to that account.

If you store the client certificate in the user store of a particular user account, it is accessible only to processes running under that user account. If you have a Windows Forms application, you can choose to install the client certificate in each user's store, or you can install it in the local machine store and place an ACL on it to allow access to each user.

Local Machine Store

When you install a client certificate in the local machine store, it is accessible only to accounts in the Administrators group and to the user who installs it. Therefore, you must add an ACL to grant access to the account used to run your application. If you have multiple ASP.NET applications on the same Web server, you can run each application in a separate application pool, using a different identity for each application, and grant access to the client certificate only to the identities that need it.

Step 1: Install a Client Certificate in the Machine Store

If you have a client certificate in a PKCS#12 (.pfx) file, you can use the Microsoft Windows HTTP Services (WinHTTP) certificate configuration tool to install the certificate and grant access to additional accounts, such as the Network Service account.

To install the certificate from a .pfx file

  1. Download the WinHttpCertCfg.exe tool from Microsoft Download Center at https://go.microsoft.com/fwlink/?linkid=20506 and install it on the client computer.

  2. Run the following command from a command window. Note that by default the WinHttpCertCfg utility is located in \program files\windows resource kit\tools.

    WinHttpCertCfg.exe -iPfxFile -c LOCAL_MACHINE\MY-ppassword

    In the above command, replace PfxFile with the name of your .pfx file. Replace password with the password of the .pfx file. If the .pfx file is not password protected, omit the -p argument.

If you do not have access to a .pfx file and you have installed Microsoft Certificate Services on a Windows Server 2003 or Windows Server 2000 computer, you can install the client certificate directly in the local machine store.

To request a client certificate from Microsoft Certificate Services and install in the local machine store

  1. Log on to the client computer by using an account with administrator privileges.

  2. Browse to the certificate authority (CA) to request a client certificate. For example, if your CA is located on the CAServer computer, browse to the following location.

    http://caserver/certsrv

  3. Click Request a certificate.

  4. Click the advanced certificate request link.

  5. Click Create andSubmit a request to this CA.

  6. In the Advanced Certificate Request form, enter a Name and e-mail address. In the Intended Purpose section, select Client Authentication Certificate. In the Key options section, check Use local machine store. Click Submit. Record the certificate name you enter because you need this later on.

    A request is generated and sent to the CA for processing.

  7. If your CA is configured to issue certificates immediately, click Install this certificate on the response page from the CA server. If your CA is configured to issue certificates after approval by an administrator, you must wait until approval is given and then return to the CA website using the same web browser to retrieve your certificate.

Step 2: Configure Access to the Certificate

In this step, you configure the ACL on the certificate in the local machine store to allow the client application to access it. If your client is a Windows Forms application, you must grant access to the user account which is running the application. If your client is an ASP.NET application and you have not configured a custom account to run ASP.NET, you must grant access to the Network Service account (the default account for running Web apps on Windows Server 2003). If you have configured a custom account to run ASP.NET, you must grant access to the custom account.

Use the following command to grant access to a specific user account:

WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "Issued_To_name" -a "Account_name"

Replace Issued_To_name with the name to which the certificate was issued. Replace Account_name with the name of a local machine or domain account. This search string is not case sensitive. The string is used to find the first enumerated certificate with a subject name that contains this substring.

The following examples show how to grant access to the Network Service account and to a custom account.

WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "SecureWebServiceClientCert" -a "NT AUTHORITY\NetworkService"

WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "SecureWebServiceClientCert" -a "MyDomain\MyAccount"

Step 3: Install the Root Certificate of the CA

If you have not already installed the root certificate of your CA, you must do so. The Microsoft Windows® operating system includes the root certificates of many external CAs pre-installed in the Trusted Root Certification Authorities certificate store.

To check if the CA root certificate is installed

  1. Run the Microsoft Management Console (MMC). On the File menu, click Add/Remove Snap-in.
  2. Select the Certificates add-in. When asked to select which certificates the add-in will manage, select Computer account and then Local machine.
  3. When you have added the Certificates snap-in, in the left pane of the MMC snap-in, expand Certificates (Local Computer).
  4. Expand Trusted Root Certification Authorities, and then click Certificates.
  5. Confirm that your CA certificate is listed.

If the CA certificate is not listed, you must install it. If the CA root certificate has been issued to you in a certificate file (for example, a .cer, .der, or .pfx file), perform the following steps:

To install the CA root certificate from a file

  1. In the left pane of the MMC snap-in, expand Certificates (Local Computer).
  2. Right-click Trusted Root Certification Authorities, and then click Import.
  3. Use the Certificate Import wizard to import the certificate from the file.

If your CA is a Microsoft Certificate Services installation, request the root certificate as follows:

To request the CA root certificate from Microsoft Certificate Services

  1. Browse to http://caserver/certsrv.
  2. Click Download a CA certificate, certificate chain or CRL.
  3. Select the CA certificate from the list, select DER for the encoding method, and then click Download CA certificate.
  4. Use MMC to install the certificate in the Trusted Root Certification Authorities folder as described in the previous procedure, "To install the CA root certificate from a file."

User Store

An alternative approach is to put the certificate in a given account's user store. This ensures that only processes running under that account can access the certificate.

Step 1: Install a Client Certificate in the User Store

The procedure for installing a client certificate in the user store varies depending on how you obtain your certificate.

To import the certificate plus private key from a PKCS#12 file into the user store

  1. Use Windows Explorer to navigate to the folder containing the .pfx file.

  2. Double-click the file to open it. The Certificate Import Wizard starts.

  3. In the Certificate Import Wizard, select the .pfx file, and when prompted, enter the password.

  4. On the Certificate Store page, select Automatically select the certificate store based on the type of certificate. Click Next, and then click Finish.

    This installs the certificate in the user store of the account you used to log on.

If you do not have access to a .pfx file, and you have installed Microsoft Certificate Services on a Windows Server 2000 or Windows Server 2003 computer, you can install the client certificate directly in the user store in the following way.

To request a client certificate from Microsoft Certificate Services and install it in the user store

  1. Browse to the CA to request a client certificate. For example, if your CA is located on the CAServer computer, browse to http://caserver/certsrv
  2. Click Request a certificate.
  3. Click Web Browser Certificate.
  4. Enter a Name and e-mail address and the other requested information, and then click Submit. A request is generated and sent to the CA for processing.
  5. If your CA is configured to issue certificates immediately, click Install this certificate on the response page from the CA server. If your CA is configured to issue certificates after approval by an administrator, you must wait until approval is given and then return to the CA website using the same web browser to retrieve your certificate.

Step 2: Install the Root Certificate of the CA

When you install a certificate in the user store, the root certificate of the CA installs automatically in the Trusted Root Certification Authorities folder in the user store. To check whether the root certificate is installed and, if not, install it, follow the steps given above in Step 3 of the local machine store instructions. However, when you add the Certificates snap-in to the Microsoft Management Console, add it for My User account, rather than a Computer account.

Calling the Web Service

When you have installed the client certificate in either the machine store or user store, you can access it from application code to call the Web service. The steps required are the same whether your client is a Windows Forms application or an ASP.NET application.

If you are using .NET Framework 1.1, you must first export the key to a DER-encoded file. This is because the System.Security.Cryptography.X509Certificates class does not contain methods to access certificate details directly from a store, but must read them from a file. See the section, "Web Services Enhancements 2.0," in this document, for an alternative approach that allows your code to retrieve certificate details directly from a certificate store.

Step 1: Export the Client Certificate to a File

This procedure exports the client certificate to a file.

To export the client certificate to a file

  1. In MMC, open the Certificates snap-in for the User store or for the local machine store, depending on where you stored the client certificate.

  2. Expand Personal, then Certificates.

  3. Right-click the client certificate, and then click Export.

  4. Click Next to move past the welcome dialog box of the Certificate Export Wizard.

  5. Confirm that No, do not export the private key is selected, and then click Next.

  6. Make sure that DER encoded binary X.509 (.CER) is selected, and then click Next.

    You must use this format because the .NET Framework does not support Base-64 or PKCS #7 formats.

  7. Enter an export file name. Note the location of the .cer export file; you will require this again in a subsequent procedure.

  8. Click Next, and then click Finish to export the certificate.

Step 2: Call the Web Service

The .NET Framework 1.1 does not contain classes to access the certificate directly in the store; therefore, you must first export the certificate to a file in a format that can be used by the client application to call the Web service.

The following code example shows how to call a Web service passing it a client certificate for authentication.

using System.Net;
using System.Security.Cryptography.X509Certificates;
...

  public void CallWebService()
  {
    // TODO: Replace with a valid path to your certificate
    string certPath = @"C:\WSClientCert.cer";

    // Instantiate the Web service proxy
    WebSvc.math mathservice = new WebSvc.math();
    mathservice.Url = @"https://wsserver/securemath/math.asmx";

    // create an X509Certificate object from the information 
    // in the certificate export file and add it to the 
    // ClientCertificates collection of the Web service proxy
    mathservice.ClientCertificates.Add(
        X509Certificate.CreateFromCertFile(certPath));

    long lngResult = 0;
    try
    {
      lngResult = mathservice.Add(Int32.Parse(operand1.Text), 
          Int32.Parse(operand2.Text));
      string result = lngResult.ToString();
    }
    catch(Exception ex)
    {
      if(ex is WebException)
      {
        WebException we = ex as WebException;
        WebResponse webResponse = we.Response;
        throw new Exception("Exception calling method. " + ex.Message);
      }
    }
  }
  

Web Services Enhancements 2.0

Web Services Enhancements 2.0 for Microsoft .NET (WSE) is a .NET class library for building Web services using the latest Web services protocols, including WS-Security, WS-SecureConversation, WS-Trust, WS-Policy, WS-SecurityPolicy, WS-Addressing, and WS-Attachments.

You do not need to use any of these protocols to access a Web service that requires client certificate authentication, but you can take advantage of the Microsoft.Web.Services2.Security.X509 class which contains methods to access a client certificate directly in the certificate store. This allows you to avoid having to export the certificate to a file, as described in step 1 of the section, "Calling the Web Service."

The following code example shows how to find the first certificate, SecureMathClient, in the local machine store and use it to call the Add method of a Web service called Math, which requires client certificates. Note that you can have more than one certificate with the same name in a certificate store; therefore, your application code should perform additional processing to select the correct certificate from those returned by the FindCertificateBySubjectString method.

  // TODO: Replace with the name of your client certificate
  string certName = "SecureMathClient";

  // WSE 2.0 method
  // Open the Local machine store
  // (Use X509CertificateStore.CurrentUserStore() to open user store)
  X509CertificateStore store =
    X509CertificateStore.LocalMachineStore(X509CertificateStore.MyStore);
  store.OpenRead();
  // Looks for the first certificate called SecureMathClient in the Local 
  // machine store
  X509CertificateCollection col= 
    (X509CertificateCollection)store.FindCertificateBySubjectString(certName);
  X509Certificate cert =null;
  try
  { 
    cert = col[0];
  } 
  catch(Exception ex)
  {
    throw new Exception("Certificate not Found!");
  }

  // Instantiate the Web service proxy
  math mathservice = new math();
  mathservice.Url = @"https://wsserver/securemath/math.asmx";
  mathservice.ClientCertificates.Add(cert);

  long lngResult = 0;
  try
  {
    lngResult = mathservice.Add(Int32.Parse(operand1.Text), 
        Int32.Parse(operand2.Text));
    result.Text = lngResult.ToString();
  }
  catch(Exception ex)
  {
    if(ex is WebException)
    {
      WebException we = ex as WebException;
      WebResponse webResponse = we.Response;
      throw new Exception("Exception calling method. " + ex.Message);
    }
  }
  

Internet Information Server 5.0 or 5.1

If your Web application runs under IIS 5.0 or 5.1, or IIS 6.0 in IIS 5.0 isolation mode, then you can still install a client certificate in the user store or the local machine store, and access it as described earlier. Note that the default account used to run ASP.NET on these installations is the local ASPNET account, and not Network Service.

In IIS 5.0, all Web applications run using the same identity. Therefore, it is not as easy to restrict access to the certificate to an individual application based on its identity.

If you must run multiple ASP.NET applications on the same IIS 5.0 or 5.1 server and you must ensure that only one of those applications can access the client certificate, you can create a serviced component and put it in an out-of-process Enterprise Services server application. You can run this application using a custom identity, and use it to access the certificate store and call the Web service.

patterns & practices Developer Center

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

© Microsoft Corporation. All rights reserved.