A Web service requiring Client certificate authentication is a common scenario.
You may have a client application which needs to send the Client certificate as part of the web request for accessing the web service.
This client application may be a Windows/Console application or another Web application.
Often you will get into issues wherein you are able to send Client certificate as part of the web request from a windows/console app but not from another web app. The primary reason for this could often be around Web app not being able to send the client cert to the target Web service.
This can happen for multiple reasons, in particular account under which Web app is running doesn't have enough permissions to access the Client cert in its local certificate store.
Refer to this excellent kb for this for more details.
In this post I want to highlight ways in which you can grant access to the Web application account to access the Client certificate in its local machine store.
When we have to send client cert as part of the web service call from a web app we need to ensure that the client cert is installed in the Local Computer -> Personal Store on the local box (where Web app is running). By default you will see the client cert installed in the Local User Store for the user who requested and installed the cert on the machine. You need to ensure first that the client cert is installed on the Local Computer Store instead of the Local User Store and then follow any of the methods below to grant access to the private key for the account (under which your web app is running).
The above article kb gives an example of granting access using the Microsoft Windows HTTP Services Certificate Configuration Tool
> WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s " IssuedToName " -a " AccountName "
> WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s " IssuedToName " -a "Network Service"
There are other ways in which you can achieve the same result. This feature is in fact built in on Windows Server 2008 within the Certificate mmc console.
Using the WSE X509 Certificate tool (This tool has features that can be used to check certificate properties).
You need to download Web Services enhancements (WSE) 2.0+ SP3 for Microsoft.Net and in the install wizard ensure you select Tools as shown below:
Once installed go ahead and launch the tool. It has a clean UI. You have the option to check certificates in the Local Computer/Current user for the available stores like Personal/Trusted/Intermediate Root CA etc. If you click on View Private Key File Properties (shown below) you can directly modify the permission for private key associated with the certificate. Basically this is just a file under C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys on Win2k3 server and C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys on Win2k8 server.
You may want to go ahead and give the Service account under which the web app is running Full permission on this file (modify the permissions from the Security tab).
If you are running the web app on Windows Server 2008/Vista there is a far simpler way built in the Certificate mmc.
Right click on the certificate and go to All Tasks -> Manage Private Keys and then give Full permission for the associated account.
Till next time..
This is Tin. I couldn't post comment from IIS automapping for some reasons. Any luck with the certificate .cer import to IIS? Thanks.
Tin, am sorry I have been stuck on lot many things lately. I will try to write this code real soon and send you in a day or so.
Tin, i have added the code snippet to the other post's comment. Please check if that helps.
I am Devaraj. We have an issue in sending client certificate using .net c#/framework1.1/win 2003/IIS6. Server on the other end is throwing "unable to retrieve client certificate". It works fine at development site. Steps followed,
1.Create an instance of System.Security.Cryptography.X509Certificates.X509Certificate
2.Then X509Certificate.CreateFromCertFile - read .der file
3.Add to server object's client certificates collection Sobj.ClientCertificates.Add(cert)
4.Invoke server object's webservice method
Permission on client certificate's private key is provided to hosted website's user mapped for anonymous access using winhttpcertcfg to both LOCAL_MACHINE\Root and \MY.
Earlier the error was "The underlying connection was closed: Could not establish secure channel for SSL/TLS." After providing permission to anonymous user - error changed to "unable to retrieve client certificate" - This seems to be providing some lead..
As obvious problem will not be at Server validating our certificate because it could successfully validate certificate sent from our development site and allow access on webservice method.
How to know that our web application on IIS at client's location(which has our application) is indeed sending a certificate? Any log on IIS? Will firewall play any role here? Unfortunately no tools can be installed at client's location.
Thanks in Advance,
Ensure we have the permission given also to the account under which your IIS process is running, i.e. give permission to the App Pool account for your web app.
I see you are using .Net 1.1, in 2.0 there is a great feature to troubleshoot such issues using System.Net Tracing.
It appears you have done this with Server 2008... Have you installed WSE on a Server 2008 box? It appears that WSE 3.0 is not supported by Server 2008...
Pete, I haven't tried WSE 3.0 on win2k8, not sure if it is not supported there. But you don't need to rely on this for a win2k8 box. you can use the in-built feature of Win2k8 (Method 3) to check for permissions in the Certificate mmc.
Sorry, but I am able to start Method 3, but I cannot find the right way to give permission to ASP.NET v4.0 which is an Apppool in IIS 7.0 . I am not able to select it because it is not found when I search. With the command line tool I tried many versions of the below:
WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "MyCert" -a "IIS APPPOOL\ASP.NET v4.0"
only to receive an "Error: No account information was found." So I think though "IIS APPPOOL" is there "ASP.NET v4.0" is not found and the name of the Application Pool is exactly what I can see in IIS Manager. I tried many variations like to omitting the dot from the name etc. but nothing worked. With Method 3 I am not able to find the apppool to add to permitted users, I am desperating. What would you recommend?
Go ahead and try adding permission for IIS_IUSRS group and see if it helps.