Setup IIS to require client certificate and to use anonymous authentication
I have a WCF web service for our customers to use. I want to protect this using client certificates. I will also use the client certificate to identify the customer.
I've made the identification part work, but I cannot make make the IIS require client certificates.
If I set the IIS to accept client certificates, the communication works and I can get the client identity using:
ServiceSecurityContext.Current.PrimaryIdentity.Name
But I can also access the site without a client certificate. I'm not sure if those without can do anything else than read the WSDL, but I don't want anyone without a trusted certificate to be able to get any information at all.
If I set the IIS to require client certificate, my test client who should have access gets the error:
The HTTP request was forbidden with client authentication scheme 'Anonymous'.
I want to allow access only to those who have a client certificate trusted by the server. Anyone else shall be rejected.
Server WCF configuration:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="ChainTrust" />
</clientCertificate>
<serviceCertificate findValue="64343ee2c8338518e78ba698f3936dc92c90db57" x509FindType="FindByThumbprint" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="DefaultBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate" />
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="WebService.Service" behaviorConfiguration="DefaultBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="DefaultBinding" contract="WebService.IService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
Client WCF configuration.
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="DefaultBehavior">
<clientCredentials>
<clientCertificate storeLocation="LocalMachine" findValue="d084c91a8f81878cd4dd991bbab348235f0fd1a3" x509FindType="FindByThumbprint" />
<serviceCertificate>
<authentication certificateValidationMode="ChainTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate" />
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://host/WebService/Service.svc"
behaviorConfiguration="DefaultBehavior" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService"
contract="WebService.IService" name="WSHttpBinding_IService">
</endpoint>
</client>
</system.serviceModel>
Best Answer
Ok we have done the same as you. We worked the other way around. We first secured IIS with the client & server certificate. We did this on IIS Express (still in development while I'm posting this). We allowed in IIS express
applicationhost.config
to overwrite specific parts of the web.config. I.e.:<section name="windowsAuthentication" overrideModeDefault="Allow" />
Server side Config :
On the client:
What helped us a lot was enable Tracing, Logging in the service and the custom authorization policy and the IIS Trace Logs.
We have
iisurl
mapped to 127.0.0.1 in our host file, so we have trusted certifcates. For the iisClientCertificationMapping check this out.Don't know if your ssl setup is correct. We have a powershell script for that. Some parts of it:
Generating the root certificate (powershell)
Generating the server certificate (command line):
Generating the server client (command line):
Binding the certificates to IIS (command line, XP specific):
change the ThumpPrint to the ThumpPrint of the certificate with subject name iisurl. I recommend you fully automate this with powershell, we have this to, so we can develop on multiple machines. But i can't past all of it here.
I hope this helps you. With this config, if you browse over https to the url iisurl/OrderService It asks you for a client certificate. (In IE)
You can also watch this log: C:\WINDOWS\system32\Logfiles\HTTPERR