C# – Passing a client certificate only works on the machine

cclient-certificatesSecurityweb services

I have a web service that is protected by requiring the consuming third party application to pass a client certificate. I have installed the certificate on the providing web service in production and on the client as well. This process is currently working fine for other clients with a similar setup. The current version is written in .NET 3.5 and works perfectly on my development machine under cassini (and running standalone), but refuses to work on my production machine with the same code and certificate setup. I have confirmed that the provider web service accepts the certificate installed on the client through the browser, but when the cert is added to a webservice call programatically, I get a 403, access is denied. I output the fingerprint of the certificate added to the call before it makes the request to the protected webservice, and it is indeed the correct certificate attached. My thinking is that somewhere along the line, it does not have access to the private key portion of the certificate.

Any ideas?

Note: I've given the IIS process access to the relevant ~/crypto directories.

This is C# and .NET 3.5

Best Answer

I had this kind of problem a couple of weeks ago. The solution in my case was to use impersonation in order to gain appropriate access to the certificate store. By default, the IIS worker thread was running as a system user, and as such had no access to the appropriate store. Adding the certificate to a specific user store, and impersonating that user solved all the issues.

I shall continue to watch this question, though, as I am aware that impersonation is not a magic bullet fix, and that there will be issues arising from it in this scenario.