.netiisclient-certificateswindows-serverwindows-server-2019

Why has the SSL Settings (client cert) behavior of IIS changed between IIS 8.5 and 10?


I am responsible for a legacy .Net 4.8 application which has MVC and API components and is only used internally. This application server has gone through an in-place upgraded from Windows Server 2012 R2 to Server 2019, thus IIS 8.5 to IIS 10. No other changes have been implemented, Group Policy is the same.

A small portion of the API is accessed by machines authenticating with preregistered client certificates. The certificate validation happens in the application via Owin middleware which means the client certificate needs to make it past IIS, so the application can act on it. On 2012R2/IIS 8.5, this was super simple, SSL settings on the specific folder where the API lives were set to accept client certs (as pictured). The application root "SSL settings" were set to Ignore, so the rest of the site, containing the views, avoided browser prompts for certificates.

IIS SSL Config Screenshot

Now on 2019/IIS10 requests containing a client cert fail with 403 - forbidden and application logging shows the request never makes it to the API. IIS now seems to assume that if a client cert is presented than it should use it for IIS based authentication, which it then fails. Am I missing something about IIS auth that was introduced with 10 - something that would allow all certs, so that my API middleware and manage authentication?

Things I've tried: Enabling "DS Mapper" via reg key for the url mapping/binding - no change in behavior.

Recreating the site level binding (:port) with netsh and enabling "Negotiate Client Certificate" will allow the cert to pass through to the API, but it then means the whole site prompts for a cert on all views. Where is this behavior for individual folders, like it used to be?

This person seems to be having the same issue.
https://serverfault.com/questions/1076490/browser-not-prompting-for-certificate-iis-10-0

Any help or ideas would be appreciated.


Solution

  • In my case, it was the behavior of the OS that changed not IIS. After configuring Failed Request Tracing, I was able to see that it was throwing a 403.16. Which led me to this page:

    https://learn.microsoft.com/en-us/troubleshoot/developer/webapps/iis/health-diagnostic-performance/http-403-forbidden-access-website

    This server had certificates in the trusted root store (a code signing cert and an external API cert) which had different issued-to and issued-from fields. After recognizing at least one cert which needed to be moved to the Intermediate cert store I ran the powershell from the page to identify the rest (get-Childitem cert:\LocalMachine\root -Recurse | Where-Object {$.Issuer -ne $.Subject} | Format-List *). After doing so, the previous behavior was restored.

    Ironically, I knew Windows server behavior regarding intermediate certs in the trusted root store has changed over the years (and how it can blow up cert validation), but just didn't cross my mind. ...silly now that I think about it.

    Here's how to enable Failed Request Tracing for the sake of posterity: https://learn.microsoft.com/en-us/troubleshoot/developer/webapps/iis/health-diagnostic-performance/troubleshoot-arr-using-frt-rules