The complete list of changes to make to activate Client Certificate Mapping on IIS using Active Directory

Setting up client certificate mapping in IIS 8.5 and above using Active Directory has never been very complex, however, I find that there is little to no documentation that walks you through the entire process from A-Z. In this article, I intend to look at setting up Client Certificate Mapping, and explain how client certificate mapping settings should work to give you more insight into these type of authentication.

When you make use of client certificates, what happens is that the browser you are working with will attempt to send a client certificate that is located on your computer to the web-server hosting the site you are trying to navigate to. In order for this to happen:

  • The website you are trying to reach must implement https (via TLS or SSL – not recommended because SSL is vulnerable to attacks) and request that connecting clients send client certificates.
  • The client browser is able to locate a client certificate on your machine that is issued by one of the certification authorities that is trusted by the web-server you are trying to connect to.

You may wish to have a look at an older article on troubleshooting client certificate issues on this blog, once you have completed your reading of this article: https://blogs.msdn.microsoft.com/friis/2011/11/15/troubleshooting-403-7-client-certificate-required-errors-step-by-step-to-make-sure-your-client-certificate-is-displayed-and-selected/

Once the client certificate is sent to the server, the web-server will perform a couple of checks on the certificate: is the certificate not expired, is the certificate issued by a certification authority that is trusted by the web-server, and has the certificate not been revoked by the certification authority that issued it?

The authentication part (or rather the mapping), will be done by a separate component, called the client certificate mapper. The module will connect to the domain controller of the domain the web-server belongs to, and will attempt to find a user account that has been associated with the client certificate that has been send over by the client browser. If such an account is found, it will be mapped to the executing request.

Setup:

The first part of the setup is to install Client Certificate Mapping using Active Directory on your IIS web-server. This component is optional and will not be present in a standard installation of IIS. The simplest way to do this is to start the Server Manager, and select the 'Add roles and features' from the Dashboard, as shown in the screenshot below:

Select a Role-Based installation from the Wizard that is launched from the Server Manager:

After selecting the server on which you wish to install the new features on from the list of servers available (generally, this will be the local server on which you have launched the Server Manager on), you will be presented with a list of Server Roles that are possible. Within the list, you need to choose the Web-Server (IIS) node in the tree view, and inside the Web-Server sub-node, and the Security feature, you will find the 'Client Certificate Mapping and Authentication'. Check this feature to install it:

Finish the Wizard to start the installation of the feature. As with other features of IIS, the installation of this component will not cause a service interruption: all your websites will continue to run, but you will need to restart the any IIS Administration consoles that were already launched prior to the install in order to view the newly installed feature in the interface.

Enabling the Client Certificate Mapping with Active Directory.

Once the feature is enabled and the IIS Management Console has been restarted (if you had a console open during the install of the component), you will be able to see the 'Active Directory Client Certificate Authentication' feature – just select the server node from the left-hand side tree view and click on the 'Authentication' icon in the central pane of the IIS Manager Console.

Enabling the 'Active Directory Client Certificate Authentication' when inside the server level Authentication feature, will perform a couple of changes that are interesting to note:

Enabling the DS Mapper on the SSL binding will allow the Active Directory Client Certificate module (authCert.dll) to look at the client certificate that has been sent by the browser on the incoming request, and attempt to map this certificate to an Active Directory account. If the DS Mapper is not enabled on the SSL binding, even if the Active Directory Client Certificate module is enabled, the client certificate mapping will not trigger.

To see if the DS Mapper is enabled or not, you can use the following NetSh command, command which you will need to run from a command line prompt with elevated privileges:

NetSh http show SSL

The command output should resemble the following:

SSL Certificate bindings:
-------------------------
IP:port : 0.0.0.0:443
Certificate Hash : <CertificateHash>
Application ID : <ApplicationIdentifier>
Certificate Store Name : MY
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Enabled
Negotiate Client Certificate : Enabled

Note that the DS Mapper Usage is set to enable. The Negotiate Client Certificate need not be set to Enabled. If this setting is enabled, the client certificate will be sent by the client browser when the initial secure connection with the web-server is negotiated. If it is disabled, an initial secure connection will be negotiated between the web-server and the browser based on the server certificate, and then the connection will be re-negotiated when the client sends the client certificate. Active Directory client certificate mapping will work even if Negotiate Client Certificate is not set to enabled.

These settings are reflected in a registry key called DefaultFlags. The key is of type DWORD32 and is located in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\SslBindingInfo\0.0.0.0:443\ . The value of the key can be one of the following values:

0 – DS Mapper disabled and Negotiate Client Certificate is disabled.
1 – DS Mapper is enabled and Negotiate Client Certificate is disabled.
2 – DS Mapper disabled and Negotiate Client Certificate is enabled.
3 – DS Mapper and Negotiate Client Certificate are both enabled.

You may change the value of this key manually using the registry editor as per the values above. However, should you do this, you will need to stop and restart the http service using the following commands for the settings to take effect:

Net stop http
Net start http

You can also apply the settings by restarting your server. This may be necessary as in some installations of Windows 2012 R2, the http service has some unregistered dependencies and will not stop correctly. Following this, it will not be possible to restart the service without a reboot.

Enabling the Client Certificate Mapping on the site level

The final step is to enable the client certificate mapping on the site or web-application level. To achieve this, select the website or web-application you wish to use this feature with and ensure the following:

  • An SSL binding is present for the website that you wish to target. This must be true for the parent website of the web-application you are trying to target as well. If the binding is not present, you should create one, and preferably perform this step before enabling the 'Active Directory Client Certificate Authentication' described in the last step – if not the DS Mapper will not be activated. A client certificate can only be sent by the browser over a secure connection.
  • In the SSL Settings for your website or web-application, the 'Require SSL' checkbox should be checked and the Client Certificates radio button should be set to 'Require'.

  • In the 'Authentication' section of the target website or web-application, you need to ensure that all other types of authentication are set to 'Disabled' as shown in the screenshot below:

If any other type of authentication is enabled (especially anonymous), the client certificate mapping will not work.

Activating the Client Certificate Mapping through code and script.

The article on the IIS.net website does list a couple of ways to enable the Client Certificate Mapping through either appcmd commands or through the usage of the IIS .Net managed APIs: https://www.iis.net/configreference/system.webserver/security/authentication/clientcertificatemappingauthentication. When executing these commands, it is important to note that only the IIS configuration will be changed. Since the DS Mapper settings are in the registry and not in the IIS configuration, the change will not be performed on the binding, hence the listings in the article will not be sufficient to enable the client certificate mapping using Active Directory.

To enable client certificate mapping using Active Directory, we will need to make some changes to the commands listed in the IIS.net article.

Using appcmd commands:

appcmd.exe set config "Default Web Site" -section:system.webServer/security/authentication/clientCertificateMappingAuthentication /enabled:"True" /commit:apphost

appcmd.exe set config "Default Web Site" -section:system.webServer/security/access /sslFlags:"Ssl, SslNegotiateCert" /commit:apphost

To these commands, we need to append the following script to enable the DS Mapper for the SSL binding:

' Connect to the WMI WebAdministration namespace.

 
Set oWebAdmin = GetObject("winmgmts:root\WebAdministration")
' Get the secure binding instances and display their properties.
Set oBindings = oWebAdmin.InstancesOf("SSLBinding")

For Each oBinding in oBindings
   IF (oBinding.Port = 443 AND StrComp(oBinding.IPAddress, "*") = 0) THEN
      Binding.SslUseDsMapper = TRUE
      oBinding.SslAlwaysNegoClientCert = TRUE
      oBinding.Put_
   END IF
Next

This script will iterate through all bindings that are configured to use port 443 and will enable both the DS Mapper and the Client Certificate Negotiation – essentially setting the registry key value for the DefaultFlags key to the value 3.

Using the managed .Net APIs for IIS

Another way of doing the same is by suing the .Net managed APIs to enable client certificate mapping:

 
using System;
using System.Text;
using Microsoft.Web.Administration;

internal static class Sample
{
   private static void Main()
   {
      using (ServerManager serverManager = new ServerManager())
      {

          Configuration config = serverManager.GetApplicationHostConfiguration();
          ConfigurationSection clientCertificateMappingAuthenticationSection = config.GetSection
                ("system.webServer/security/authentication/clientCertificateMappingAuthentication",
                    "Default Web Site");
          clientCertificateMappingAuthenticationSection["enabled"] = true;
         
          ConfigurationSection accessSection = config.GetSection
                ("system.webServer/security/access", "Default Web Site");
          accessSection["sslFlags"] = @"Ssl, SslNegotiateCert";

          //iterate through the sites on the server and get the site named 'Default Web Site'
          Site selectedSite = serverManager.Sites.Where(s => s.Name.Equals("Default Web Site",

          StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
          if (selectedSite != null)
          {
                //iterate through the bindings of the site and attempt to retrieve an https binding

Binding sslBinding = selectedSite.Bindings.Where(b => b.Protocol.Equals("https",
StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

         if (sslBinding != null)
{
              //enable the DS Mapper
               sslBinding.UseDsMapper = true;
}
}

     serverManager.CommitChanges();
}
}
}

In the code above, we use LINQ to objects to iterate through all the sites in the ServerManager's sites collection object, searching for a site called 'Default Web Site'. If your site is named differently, change this line to match the name of the site you are targeting. Following this, if we can find a site, we will iterate in the same way through the bindings of the site searching for a binding that is using 'https'.

When the binding is found, we set the UseDsMapper property of the binding to true to enable the DS Mapper. This does not need any service restart or server reboot to take effect since we are going through the APIs to enable the mapper. If you intend to copy the code above, make sure that you check that the quote symbol (") is correct and that dashes (-) have not been replaced by long dashes by the browser when displaying the article.

By Paul Cociuba
Follow what I read: https://linqto.me/about/pcociuba