I'm trying to setup IIS 8 (Windows Server 2012) to accept client certificates for an ASP .NET website. First I created a self signed certificate and a client certificate:
makecert.exe -r -n "CN=MyCompany" -pe -sv MyCompany.pvk -a sha1 -len 2048 -cy authority MyCompany.cer makecert.exe -iv MyCompany.pvk -ic MyCompany.cer -n "CN=MY Client" -pe -sv MyClient.pvk -a sha1 -len 2048 -sky exchange MyClient.cer -eku 1.3.6.1.5.5.7.3.2 pvk2pfx.exe -pvk MyClient.pvk -spc MyClient.cer -pfx MyClient.pfx -po THE_PASSWORD
I imported the root certificate MyCompany.cer on the IIS server using the mmc/certificates plugin, into the Trusted Root Certificates for Local Machine.
Then on IIS Manager/SSL Settings I selected the "Accept" radio button to allow the website accept client certificates.
On the client side a have a C# test console app that loads the client cert MyClient.pfx file and calls a WebAPI endpoint:
var certHandler = new WebRequestHandler(); certHandler.ClientCertificateOptions = ClientCertificateOption.Manual; certHandler.UseProxy = false; var certificate = new X509Certificate2(File.ReadAllBytes(@"C:\MyClient.pfx"), "THE_PASSWORD"); certHandler.ClientCertificates.Add(certificate); var client = new HttpClient(certHandler); var result = client.GetAsync("https://MyServer/api/MyEndpoint").Result; string resultStr = result.Content.ReadAsStringAsync().Result; Console.WriteLine(resultStr);
I'm getting back a 403 error:
403 - Forbidden: Access is denied. You do not have permission to view this directory or page using the credentials that you supplied.
I also imported the MyClient.pfx certificate in Chrome and open the url. Chrome prompts for the client certificate. I select My Client but I still get the 403 error. If I click Cancel instead the page loads. I guess that's fine because IIS is configured to Accept (not Require) client certs.
My third test was setting up the same site on my machine's IIS (Windows 7). I imported MyCompany.cer, setup SSL Setting to Accepted. This time everything worked, no 403 error. My WebAPI can access the certificate with no problem.
What am I missing?
-- Update 1
I enabled Failed Request Tracing on the site. This is what I get:
<failedRequest url="https://myserver:443/" siteId="35" appPoolId="CertTest" processId="7248" verb="GET" authenticationType="NOT_AVAILABLE" activityId="{00000000-0000-0000-B0AA-0280000000E0}" failureReason="STATUS_CODE" statusCode="403.16" triggerStatusCode="403.16" timeTaken="0" xmlns:freb="http://schemas.microsoft.com/win/2006/06/iis/freb"></failedRequest>
If I understand right the error is 403.16. I understand that happens when the certificate on the server is not imported into the Trusted Root Certification Authorities under Local Computer. I double checked and that's not my case.