Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

X.509 certificates on WCF?

Problem :

I'm developing this program on one machine.

The service works fine in development server, but when I try to host the service in IIS it gives me an error that:

Cannot find the X.509 certificate using the following search criteria: StoreName 'My', StoreLocation 'CurrentUser', FindType 'FindBySubjectName', FindValue 'WCFServer'.

So is there anyway I can resolve this? I'm trying this code from

http://www.codeproject.com/KB/WCF/9StepsWCF.aspx

certificate creation

makecert.exe -sr CurrentUser -ss My -a sha1 -n CN=WCfServer -sky exchange -pe
makecert.exe -sr CurrentUser -ss My -a sha1 -n CN=WcfClient -sky exchange -pe

Certificate is present in Personal and Trusted People folder in MMC

Service has one function which accepts a number and returns string and works fine

This is my service web.config:

<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding">
          <security>
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="WCFServiceCertificate.Service1" behaviorConfiguration="WCFServiceCertificate.Service1Behavior">
        <!-- Service Endpoints -->
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="WCFServiceCertificate.IService1">
          <!--
              Upon deployment, the following identity element should be removed or replaced to reflect the
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity
              automatically.
          -->
          <!--<identity>
            <dns value="localhost"/>
          </identity>-->
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFServiceCertificate.Service1Behavior">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </clientCertificate>
            <serviceCertificate findValue="WcfServer"
                                storeLocation="CurrentUser"
                                storeName="My"
                                x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

This is my Client Config

<system.serviceModel>
                <bindings>
   <wsHttpBinding>
    <binding name="WSHttpBinding_IService1" closeTimeout="00:01:00"
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
     bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
     maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
     textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
      maxBytesPerRead="4096" maxNameTableCharCount="16384" />
     <reliableSession ordered="true" inactivityTimeout="00:10:00"
      enabled="false" />
     <security mode="Message">
      <transport clientCredentialType="Windows" proxyCredentialType="None"
       realm="" />
      <message clientCredentialType="Certificate" negotiateServiceCredential="true"
       algorithmSuite="Default" establishSecurityContext="true" />
     </security>
    </binding>
   </wsHttpBinding>
  </bindings>
                <client>
   <endpoint address="http://localhost:1387/Service1.svc" behaviorConfiguration="CustomBehavior"
    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
    contract="ServiceReference1.IService1" name="WSHttpBinding_IService1">
    <identity>
     <certificate encodedValue="AwAAAAEAAAAUAAAA9YoGKvsMLFkeO1WjaCLReQuz1ysgAAAAAQAAALUBAAAwggGxMIIBX6ADAgECAhDDvb3bnmzhsERpNTWEBYQXMAkGBSsOAwIdBQAwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3kwHhcNMTEwMzA0MDcwNzU3WhcNMzkxMjMxMjM1OTU5WjAUMRIwEAYDVQQDEwlXY2ZTZXJ2ZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM9e4DwCDYJ4l6myt1QadHzXoqCH2wa1aUjiab1aK/7d/1LZ00KfPJw8kKB358serjEi9SMg0UeyGtl0+byJ8PqShfv4MUTHZcPaWy99vHaYHwH7T9hVwY5RANBWyFy6nf1rXDh/cB2qm0Q/xN5xElOtheFqUoL8Ua6fcP33BAWPAgMBAAGjSzBJMEcGA1UdAQRAMD6AEBLkCS0GHR1PAI1hIdwWZGOhGDAWMRQwEgYDVQQDEwtSb290IEFnZW5jeYIQBjdsAKoAZIoRz7jUqlw19DAJBgUrDgMCHQUAA0EAKlaHJQNdC9VgPuHlVuniQJd+fHoVOU62nl374iXYdQus5KDgKz9RHWAtjhpToBB4sOXOnwTkJfcyJWBf6J14Mw==" />
    </identity>
   </endpoint>
  </client>
                <behaviors>
                        <endpointBehaviors>
                                <behavior name="CustomBehavior">
                                        <clientCredentials>
                                                <clientCertificate findValue="WcfClient"
                               x509FindType="FindBySubjectName"
                               storeLocation="CurrentUser"
                               storeName="My"/>
                                                <serviceCertificate>
                                                        <authentication certificateValidationMode="PeerTrust"/>
                                                </serviceCertificate>
                                        </clientCredentials>
                                </behavior>
                        </endpointBehaviors>
                </behaviors>
        </system.serviceModel>

and simply calling the service at client end using this

 Service1Client obj = new Service1Client();
            Response.Write(obj.GetData(12));

Now when I run everything works fine without an issue.

As you can service is running at development server.

But when i try to host the service in IIS it gives me an error that

Cannot find the X.509 certificate using the following search criteria: StoreName 'My', StoreLocation 'CurrentUser', FindType 'FindBySubjectName', FindValue 'WCFServer'.

So is there anyway I can resolve this?

like image 852
Nguyễn Văn Thắng Avatar asked Jul 14 '12 09:07

Nguyễn Văn Thắng


3 Answers

As x0n mentioned, Cassini will run as your current user, but IIS will run as IUSR. Import the certificate, with private key, into LocalMachine\Personal (LocalMachine\My), and change your service config from this:

        <serviceCertificate findValue="WcfServer"
                            storeLocation="CurrentUser"
                            storeName="My"
                            x509FindType="FindBySubjectName" />

To this:

        <serviceCertificate findValue="WcfServer"
                            storeLocation="LocalMachine"
                            storeName="My"
                            x509FindType="FindBySubjectName" />
like image 149
zimdanen Avatar answered Oct 08 '22 08:10

zimdanen


You will maybe have to set up dns value, meaning name of the Certificate, in the client>endopoint >indentity (as it is described in the code below )

<client>
        <endpoint address="http://localhost/FrontPMWebServiceSetup111/FpmService.svc"
          binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService"
          contract="FPMServiceReference.IService" name="WSHttpBinding_IService">
          <identity>
            <dns value="WCfServer" />
          </identity>
        </endpoint>
      </client>
like image 2
goblini Avatar answered Oct 08 '22 08:10

goblini


Install the certificate in "My" for the computer store in order to have it available for all users. You have it installed in "My" for the current user. The development server runs as the current user, so that's why it works.

like image 1
x0n Avatar answered Oct 08 '22 07:10

x0n