IIS 7 and Above
IIS Client Certificate Mapping/Authentication Does Not Appear to Work...
Last post May 16, 2020 12:02 PM by TWebby1763
Dec 16, 2018 04:12 PM|TWebby1763|LINK
Apologies in advance for the length, but I wanted to thoroughly document my analysis of this issue.
I have spent an inordinate amount of time (weeks and weeks) Googling/researching/testing/debugging the IIS Client Certificate Authentication security scenario for WCF Web Services. And, in short, while acknowledging that I could very well be mistaken, based
on my results, I have come to the conclusion that there is either a bug in either IIS Web Site/Application Authentication; .Net Web Client Authentication configuration, or both.
The problem in short appears to be that there is currently no way for a web client to authenticate to IIS via X.509 certificate, without enabling "Anonymous Authentication" in IIS. I believe this to be a bug because in addition to the reasons laid out below,
in my opinion, this behavior is completely inconsistent with the other IIS Authentication schemes, and there is no logical reason for such a requirement. Depending on the configuration settings, attempts to implement client certificate authentication, without
enabling Anonymous Authentication in IIS, result in one of the following errors, which I believe indicate an issue with how certificate authentication is implemented in .Net and/or IIS:
#1 Exception: System.ServiceModel.ServiceActivationException: The service 'MyService.svc' cannot be activated due to an exception during compilation. The exception message is:
Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service.. ---> System.NotSupportedException:
Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service.
#2 System.ServiceModel.ServiceActivationException: The service 'MyService.svc' cannot be activated due to an exception during compilation. The exception message is:
The authentication schemes cannot be inherited from the host for binding 'CustomBinding'. No AuthenticationScheme was specified on the ServiceHost or in the virtual application in IIS. This may be resolved by enabling at least
one authentication scheme for this virtual application in IIS, through the ServiceHost.Authentication.AuthenticationSchemes property or in the configuration at the <serviceAuthenticationManager> element.. --->
#3 System.ServiceModel.ServiceActivationException: The service '/SecureWCFSvc/EmployeeGetSvc.svc' cannot be activated due to an exception during compilation. The exception message is:
The value of the property 'authenticationScheme' cannot be parsed. The error is: The enumeration value must be one of the following: None, Digest, Negotiate, Ntlm, IntegratedWindowsAuthentication, Basic, Anonymous.. --->
The first error CLEARLY indicates that A. Anonymous Authentication is disabled for the IIS web app. And B. The web client/service configuration settings (Transport.clientCredentialType="Certificate") dictate that
Anonymous Authentication be enabled in IIS for the web app.
In the second error, the web app (IIS) configuration is indicating that NO authentication scheme has been specified, when in fact the iisClientCertificateMappingAuthentication scheme has been enabled for the web app in IIS.
Finally, when attempting to use a custom binding with authenticationScheme="Certificate", the response is basically that there is no such authentication scheme, and that one must be selected from the enumerated values that are helpfully provided in the exception
message. Which of course begs the question: Where is the value that maps to the IIS "iisClientCertificatMappingAuthentication" Authentication Scheme?
Here are the pertinent settings/configuration/setup steps:
1. Configured web site/app for SSL with valid self-signed Cert
2. IIS Certificate Mapping correctly configured and enabled in applicationHost/web site/web app config files:
<iisClientCertificateMappingAuthentication enabled="true" oneToOneCertificateMappingsEnabled="true"
<add userName="wcfUser" password="[enc:IISCngProvider:iEncoded Value=:enc]" certificate="Encoded Cert String" />
3. All Authentication modes disabled in IIS Manager/Authentication settings UI
Web Service/Client App:
1. Specify Transport Client Credential Type = "Certificate" in both service and app bindings:
<binding name="wsHttpTransportCertBinding" >
<security mode="Transport/TransportWithMessageCredential" >
<transport clientCredentialType="Certificate" />
<message clientCredentialType="Certificate" negotiateServiceCredential="false" establishSecurityContext="false" />
2. Delete or specify same binding for Mex endpoint
3. Specify valid self-signed Client Cert in client app.config <clientCredentials> section
1. Using above settings/configuration
Result: Exception #1 above: "Security settings for this service require 'Anonymous' Authentication"
Why is enabling Anonymous Authentication in IIS required for a Client Credential Type of "Certificate", while when I specify a Client Credential Type of "Basic", I can enable ONLY Basic Authentication in IIS, and the service works as expected?
2. Enable "Anonymous Authentication" for site/application
Service method successfully called with
mapped certificate user account shown in IIS logs!!!
***Now here's the kicker***
3. Set binding to INHERIT the authentication scheme from host
Result: - Exception #2 above: "No AuthenticationScheme was specified on the ServiceHost or in the virtual application in IIS"
How can this be when the iisClientCertificatMappingAuthentication Scheme is CLEARLY enabled for the web site/application??? Why does the exception indicate that no authentication scheme has been specified, when clearly it has?
4. Configure Custom Binding with CertificateOverTransport
Result: - Exceptions comparable to above wsHttpsBinding errors.
5. Implement various IIS/.Net configuration steps outlined in numerous posts, blogs, and forum answers.
Result: - My early experience was that on several occasions, the posted "solution" actually appeared to work...Initially. But what I found, was that when I re-published my web service app to IIS, the Anonymous Authentication
scheme was "silently" re-enabled on the web app. Once I discovered this, and again disabled it, I was back to receiving the usual exceptions. Because of that, I added code explicitly disabling Anonymous Authentication to my service's web.config file, to prevent
that behavior going forward. I suspect that this same behavior may have occurred with others, and that the "false positives" were not discovered (if then) until after the purported "solutions" were publicly posted.
The error conditions I've documented above are why it appears that there is a bug, but it's not clear which side is the culprit. In other words, is IIS indicating to the .Net client that NO authentication scheme has been enabled, even though it has? OR,
is it that IIS actually indicates to the client app that the iisClientCertificateMappingAuthentication scheme is indeed enabled, but for whatever reason, .Net either doesn't map the IIS scheme to "Certificate"; erroneously maps "Certificate" to the "Anonymous"
authentication scheme, or falls back to that Anonymous because the enumeration mapping to the IIS iisClientCertificateMappingAuthentication scheme is missing/invalid/not implemented on the .Net side? Or some combination of both, or other? Whichever is the
case, in my mind, there clearly appears to be an issue here.
1. At this point, why is there STILL no "Certificate Authentication" option in IIS Manager UI available for Web Site/Applications' Authentication settings?
2. In .Net web.config, why is there no authenticationSchemes enumeration value that corresponds to the IIS iisClientCertificateMappingAuthentication scheme?
3. If this is indeed an issue of "lack of guidance" rather than a bug, why has Microsoft provided such extensive documentation (and examples) for IIS and WCF configuration, but has glaringly omitted guidance for implementing one of the most common, asked-about,
and apparently most difficult to implement business use-cases?
In my humble opinion, Microsoft should do one (or more) of the following:
1. Acknowledge that this is a bug. Commit to fixing it, and then do #3.
2. Acknowledge that this is a bug and that they are NOT going to fix it (and why), and CLEARLY indicate that developers must enable Anonymous Authentication in IIS in order to implement Client Certificate Authentication, instead of requiring developers to spend
hours/days/weeks googling Stackoverflow and blogs for the answer...Which, because any developer worth his salt, isn't going to take at face value, results in frustration and wasted time spent trying to verify what seems to be an inexplicable requirement.
Also, by making such a public acknowledgement, Microsoft will not only save untold man-hours in wasted effort, it will also allow developers to point at official Microsoft guidance, when explaining (justifying) to internal sysadmins, clients, and third-parties
why they must enable Anonymous Authentication on their web site(s)/app(s) if they want clients authenticated by
3. Provide clear guidance (documentation and examples) in Microsoft Docs on both the server and client configurations for correctly implementing
Client Certificate Authentication in IIS WITHOUT enabling Anonymous Authentication.
Again, I acknowledge that I am NOT an expert, and could very well be mistaken in my analysis of this issue, and would welcome any guidance and/or references to successful implementations of this use case.
Any and all responses welcomed.
Dec 16, 2018 06:24 PM|mbanavige|LINK
have you gone through this guidance to see if anything was overlooked during the setup?
Dec 17, 2018 02:48 PM|TWebby1763|LINK
Thanks for your response, and my apologies for not responding sooner. During the day yesterday, I checked email sporadically for a notification that my post had been approved/responded to, but did not receive any. This morning, I just checked the forum on
a whim, and saw that you had responded.
As far as verifying that the certificate has been mapped correctly/all steps followed, indeed I have (numerous times actually). I have an entry in my applicationHost.config file with the same pertinent attributes/values as the example from that link. But
more importantly, as I stated in my post, I'm pretty certain IIS Client Certificate Mapping has been correctly configured, because when I enable Anonymous Authentication on the web site/application, the service is correctly called, and the username of the
Windows account that the client certificate is mapped to, is logged by IIS as the "cs-username".
I'm curious as to your thoughts on my statements regarding the apparent lack of a corresponding .Net enumeration value for the "Certificate" authenticationSchemes attribute, while providing values of "None", "Digest", "Negotiate", "Ntlm", "IntegratedWindowsAuthentication",
"Basic", and "Anonymous", and the fact that a "Security settings for this service require 'Anonymous' Authentication..." exception is thrown when "Certificate" is specified as the Transport clientCredentialType value, but when other enumerated values are
provided, exception messages include the description of the IIS authentication scheme that actually corresponds to the clientCredentialType value specified?
Dec 26, 2018 06:17 AM|Brando Zhang|LINK
Could you please tell me the IIS version you have used now?
Does you application host has enable some other setting?
Dec 27, 2018 12:13 PM|TWebby1763|LINK
Hi Brando Zhang,
Thanks for responding.
I am using IIS version 10.0.17763.1.
"Does you application host has enable some other setting?"
Jan 01, 2019 06:17 AM|Brando Zhang|LINK
What I mean is I suggest you could check your application.host config file, maybe it has enable other setting.
Jan 01, 2019 03:10 PM|TWebby1763|LINK
I have been checking my application.host config file very closely while testing...That's how I know that client certificate mapping has been enabled:
<iisClientCertificateMappingAuthentication enabled="true" oneToOneCertificateMappingsEnabled="true".../>
Is there another applicationHost.config setting you believe could be affecting IIS/.Net inability to authenticate a client via X.509 Cert without enabling anonymous authentication in IIS?
Do you have any thoughts on the questions I asked mbanavige (which have yet to receive a response):
"I'm curious as to your thoughts on my statements regarding the apparent lack of a corresponding .Net enumeration value for the 'Certificate' authenticationSchemes attribute, while providing values of 'None', 'Digest', 'Negotiate', 'Ntlm', 'IntegratedWindowsAuthentication',
'Basic', and 'Anonymous', and the fact that a 'Security settings for this service require 'Anonymous' Authentication...' exception is thrown when 'Certificate' is specified as the Transport clientCredentialType value, but when other enumerated values
are provided, exception messages include the description of the IIS authentication scheme that actually corresponds to the clientCredentialType value specified?"
Please keep in mind that everything works exactly as it should as long as Anonymous authentication (or one of the other schemes such as "Basic" or "Windows") is enabled in IIS, and that I've pointed out some glaring and completely inconsistent and illogical
behavior around .Net and IIS' handling of certificate authentication, that nobody seems willing or able to address.
Again, and as always, thank you very much for your response Brando.
Happy Holidays and best wishes in 2019
Jul 10, 2019 02:45 AM|DRNolan|LINK
Aug 13, 2019 07:06 PM|TWebby1763|LINK
Amazingly, no one from Microsoft, or any insiders (MVPs, ect.) have offered any insight or meaningful response on this issue. It kinda boggles the mind that apparently, a large number of developers are either unaware of the issue, or that have simply chosen
to enable anonymous access, and just move on without raising the issue.
May 13, 2020 10:17 PM|Mark P. Hahn|LINK
Actually, I do think this works, but in a very confusing manor. Yes, we spent around 3 days, with four separate people looking at this to figure it out.
The settings for iisClientCertificateMapping are in the applicationHost.config file, but it needs to appear multiple times. Once at the host (or server) level, and then again at either the Site or Application level.
I got this working by using the IIS Manager, then examining the applicationHost.config file. First, in IIS Manager, I set the mapping I wanted at the server level using the Configuration Editor in the Management group for the server. There, in the section
system.webServer/security/authentication/iisClientCertificateMappingAuthentication, I set Enabled to True and setup the mappings.
Next I went to the site level, opened the Configuration Editor again for section system.webServer/security/authentication/iisClientCertificateMappingAuthentication and set Enabled to True. I again setup the same mapping records. (This may be redundant, I'm
not sure.) Note: to the right of the section selector there will now be a drop down with two different xml paths. However, only one is editable here.
At this point it worked. I used Postman for testing. Certificates for the CA, the Server and the Client were all created with mkcert and the transformed as needed with openssl. (That last sentence is about 3-4 hours of fiddly work to get the right certificates
in all the right places with all the right formats. I cribbed notes from here: https://docs.microsoft.com/en-us/archive/blogs/asiatech/how-to-create-an-iis-website-that-requires-client-certificate-using-self-signed-certificates).
I examined applicationHost.config in C:\Windows\System32\inetsrv\config and discovered that the tag <iisClientCertificateMappingAuthentication> appeared twice. Once on line 323 with this xml path:
<configuration> - <system.webServer> - <security> - <authentication> - <iisClientCertificateMappingAuthentication>
and again at line 862 with this xml path:
configuration - <location path="Default Web Site"> - <system.webServer> - <security> - <authentication> - <iisClientCertificateMappingAuthentication>
Your line numbers will differ but it should be in the ballpark.
Your mileage may vary, -MpH
May 16, 2020 12:02 PM|TWebby1763|LINK
Thank you very much for your response.
Ultimately, I ended up just enabling "Anonymous" access and moving on. :(
Unfortunately at this point, I am eyes-deep in other projects at the moment, and it will be a while before I will be able to circle back to try to build a project to implement your solution to this issue that you and your team obviously spent a good deal
of effort to investigate, and apparently have resolved.
It is definitely my intention is to revisit this at some point, and post my results.
Again, I greatly appreciate all your work on this, and in the meantime, gratefully accept your answer as the solution.