How to configure IIS Express to ask for client certificate

Does anybody know how to configure IIS Express to require client certificate for access? I'm trying to debug a problematic ASP.NET application which uses client certificates for authentication.


Solution 1:

Use the IIS Manager tool and follow the Microsoft documentation IIS Client Certificate Mapping Authentication <iisClientCertificateMappingAuthentication>.

Sample config:

<location path="Default Web Site">
   <system.webServer>
      <security>
         <authentication>
            <windowsAuthentication enabled="false" />
            <anonymousAuthentication enabled="false" />
            <digestAuthentication enabled="false" />
            <basicAuthentication enabled="false" />
            <iisClientCertificateMappingAuthentication enabled="true"
                  manyToOneCertificateMappingsEnabled="true">
               <manyToOneMappings>
                  <add name="Contoso Employees"
                        enabled="true"
                        permissionMode="Allow"
                        userName="Username"
                        password="[enc:AesProvider:57686f6120447564652c2049495320526f636b73:enc]">
                     <rules>
                        <add certificateField="Subject"
                           certificateSubField="O"
                           matchCriteria="Contoso"
                           compareCaseSensitive="true" />
                     </rules>
                  </add>
               </manyToOneMappings>
            </iisClientCertificateMappingAuthentication>
         </authentication>
         <access sslFlags="Ssl, SslNegotiateCert" />
      </security>
   </system.webServer>
</location>

Solution 2:

I found a blog that detailed how to configure client certificate requests for IIS Express (I used Visual Studio 2017, IISExpress 10.0). Apparently the location of the applicationhost.config files changed in Visual Studio 2015 and up.

Here's an outline of what it says:

  1. Install the certificate (note the private key is only necessary from the client side) on the development machine (it should be visible in browser's certificate lists in their settings)
  2. Using Visual Studio, create a new web application
  3. Enable SSL for your project: View the properties of the project (F4) -> SSL Enabled to True (notice the SSL URL property gets populated)
  4. Set your project to start in SSL mode: Go to Project Properties (Alt+Enter), select the Web tab and modify the Project Url to the one from step 3. E.g. https://localhost:44300
  5. Locate the IIS Express config file applicationhost.config: In 2015 or 2017, the file is located in [solution directory]\.vs\config\ - in earlier versions it's found in %UserProfile%\Documents\IISExpress\config\
  6. Modify the applicationhost.config file: Set <access sslFlags="Ssl, SslNegotiateCert, SslRequireCert" /> and <iisClientCertificateMappingAuthentication enabled="true"></iisClientCertificateMappingAuthentication>
  7. The certificate is now available from the code in the Request.ClientCertificate property, and should be prompted when you open your page in the browser.

Solution 3:

These were the instructions handed out by Jason Shavers in his blog. (But that page no longer exists.) Scott Hanselman also talks about enabling SSL at http://www.hanselman.com/blog/WorkingWithSSLAtDevelopmentTimeIsEasierWithIISExpress.aspx . But at no point does he refer to making the site require client certificates.

These are the instructions I followed:

Change applicationhost.config (There are two of these one at MyDocuments\IISExpress\config and the other at program files\IIS Express\AppServer by default the one under your profile is used when you run a project on IISExpress in VS 2012 The other can be run using the command line which is what I did on the local test machine.)

  1. Change the element

< access sslFlags="None" / > to < access sslFlags="SslNegotiateCert" />

And the element

< iisClientCertificateMappingAuthentication enabled="false" > < / iisClientCertificateMappingAuthentication >

to

< iisClientCertificateMappingAuthentication enabled="true" > < / iisClientCertificateMappingAuthentication >

The next two steps have to both be performed in Visual Studio By default when a new project is create in VS 2012 then it is created as an IIS Express project. An older project transferred to VS2012 may have to actually change that setting.

  1. On the Project properties page on the Web tab, change Use Visual Studio Developer Server to Use Local IIS web Server. (There should be a grayed out checkbox saying Use IIS Express if you don't have regular IIS install on you machine (which can't be done on these NMCI machines.) There should be a project URL saying something like http://Localhost:62714/ (which should be the same port that is set as "specific port" under the Visual Studio Development Server setting (if it is set)

  2. Then select the Project on the solution explorer and go to the properties tab. (Sometimes this has to be done a couple of times before the properties show up.) This will have three properties, SSL Enable which defaults to false, SSL URL which is blank with a new project and URL which is set to the URL in "project URL" on the properties tab.

Change the SSL enabled property to true, and a new SSL URL will be created.

  1. Copy that SSL URL and go back to the project properties page and paste that in there as the new Project URL. I hit "Create Virtual Directory" at this point although some blogs say that is not necessary that you only need save the project and run it in debug.

On the applicationhost.config file under the the "" element a new entry is made when the project is first run before you enable SSL. It will look like this:

        <site name="WebApplication1" id="2">
            <application path="/" applicationPool="Clr4IntegratedAppPool">
                <virtualDirectory path="/" physicalPath="c:\users\edward.joell\documents\visual studio 2012\Projects\WebApplication1\WebApplication1" />
            </application>
            <bindings>
                <binding protocol="http" bindingInformation="*:61313:localhost" />
            </bindings>
        </site>

When you enable SSL on your project, it should look like this:

        <site name="WebApplication1" id="2">
            <application path="/" applicationPool="Clr4IntegratedAppPool">
                <virtualDirectory path="/" physicalPath="c:\users\edward.joell\documents\visual studio 2012\Projects\WebApplication1\WebApplication1" />
            </application>
            <bindings>
                <binding protocol="http" bindingInformation="*:61313:localhost" />
    <binding protocol="https" bindingInformation="*:44313:localhost" />
            </bindings>
        </site>

(all 443xx ports are reserved for SSL projects).