views:

1809

answers:

3

Ok, I have seen several questions related to this issue, and I have tried a lot of the ideas presented in them with no success. Here's my situation:

I'm hitting a web service over my company's intranet. I have used svcutil.exe to generate the client class for WCF. I was able to run the web service call with no problem when the service was in development and did not require authentication credentials, so I know the code works. At the time, the code was running over SSL. I imported the required certificate into the Trusted Root Certification Authorities store, and everything was fine.

We just moved to a stage environment, and the service was upgraded to require credentials to connect. I switched my connection to the new endpoint, and added code to authenticate. This is my first time working with wcf, so please bear with me on any obvious mistakes. My problem is that I cannot locate the certificate via code to pass to the service for authentication. I am basing this off of some online code examples I found.

Here is an example of my config generated by svcutil:

<system.serviceModel>
  <bindings>
   <basicHttpBinding>
    <binding 
        name="xxxSOAPBinding" 
        .... (irrelevant config settings)....
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
      maxBytesPerRead="4096" maxNameTableCharCount="16384" />
     <security mode="Transport">
      <transport clientCredentialType="Certificate" />
     </security>
    </binding>
   </basicHttpBinding>
  </bindings>
  <client>
   <endpoint address="https://xxxServices_1_0_0"
    binding="basicHttpBinding" bindingConfiguration="xxxSOAPBinding" 
    contract="xxxService" name="xxxService" />
  </client>
 </system.serviceModel>

And here is the code I am using to try to connect. The exception is thrown as soon as I attempt to locate the certificate:

using (var svc = new xxxServiceClient())
{
    svc.ClientCredentials.UserName.UserName = "XXX";
    svc.ClientCredentials.UserName.Password = "XXX";

    svc.ClientCredentials.ClientCertificate
     .SetCertificate(StoreLocation.LocalMachine, StoreName.Root, 
                     X509FindType.FindBySubjectName, "xxx");
...
}

I have tried several different X509FindTypes, and matched them to the values on the cert with no success. Is there something wrong with my code? Is there another way I can query the cert store to validate the values I am passing?

The dev machine where I am running Visual Studio has had the cert imported.

+2  A: 

Two silly questions:

  • are you sure your certificiate is installed at all?
  • is this a certificiate specifically for this staging machine?

Also, it seems a bit odd you're first of all setting username/password, and then also setting the credential. Can you comment out the username/password part? Does that make any difference?

Marc

marc_s
Beat me by 20 seconds. :)
Randolpho
<hehe> - I know the feeling - I've had the dreaded orange "another answer has been posted" banner pop up at me countless times :-)
marc_s
I think it is installed. I thought I was verifying this by checking the Certificates dialog. When I do this, I can see the cert under the Trusted Root Certification Authorities tab. Do I need to check anything else to verify?The cert is not specific for the machine. It is used across the network for our web services.
Mark Struzinski
@Mark: the "Trusted Root Certificiation Authorities" is the store for the ISSUERS (certificate authority) of certificates that you trust. You need to put your actual certificate somewhere else, typically under "Personal certificates" (even on a computer account).
marc_s
Importing the cert to the personal store and changing the StoreLocation to CurrentUser, StoreName to My, and X509FindType to FindByThumbprint did the trick. Thanks!
Mark Struzinski
+1  A: 

This may sound stupid, but are you certain the new cert for the staging service has been installed into your cert store? That's most likely your problem.

Also, since you didn't mention what exception is thrown, it's possible the problem is that you've set username/password credentials before setting clientcertificate credentials, when your binding does not indicate the use of username/password. Could be a problem there; they're mutually exclusive, IIRC.

Randolpho
+2  A: 

Are you sure the the certificate has been imported to the local machine store, it could be in the CurrentUser store.

Shiraz Bhaiji
How can I import certificate into local machine store?
knagode