none
WCF Exception - The client certificate is not provided. Specify a client certificate in ClientCredentials. RRS feed

  • Question

  • After reading most of what I have been able to find on this subject, and attempting many different options, I am not making any progress, and hence this post.

    I wish to use SSL with a self-hosted WCF service, having security mode as TransportWithMessageCredential with HTTP transport. I am using 2 dev machines and testing over a LAN.

    As mentioned above, I have read and meticulously followed just about every example which demonstrates this, yet somehow still have issues with the certificates.

    As far as the certificates are concerned, I have tried a number of things.

    The main "jist" of what I did was to follow what is given inhttp://msdn.microsoft.com/en-us/library/ff647171.aspx

    I also used “How to: Use Certificate Authentication and Message Security in WCF Calling from Windows Forms” in http://msdn.microsoft.com/en-us/library/ff648360.aspx  as a basic guide.

    I first tested the service and client using basicHttpBinding over Http in order to verify things.

    I then made changes for wsHttpBinding, SSL, and Certificates.

    When I “Add Service Reference” on the client dev PC, I receive an error as follows

    A windows titled "Security Alert" opens with the following content:

    Visual Studio has detected a problem with the site's security certificate.

    Issued By: RootCATest Issued to: TempCert Certificate is valid from---

    The security certificate issued by a company is not in the untrust list. It might be trustable.

    The security certificate date is valid.

    The security certificate for host 'TempCert' does not match the name of the page you are trying to view.

    Do you want to proceed (Yes / No)

    If I click “Yes” to proceed, and run the client code, an InvalidOperationException occurs with the following message.

    “The client certificate is not provided. Specify a client certificate in ClientCredentials.”

    The Service config is as follows:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.serviceModel>
            <behaviors>
                <serviceBehaviors>
                    <behavior name="ServiceBehavior">
                        <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
                        <serviceDebug includeExceptionDetailInFaults="true" />
                        <serviceCredentials>
                            <serviceCertificate findValue="CN=TempCert" 
                                                storeLocation="LocalMachine"
                                                storeName="My" />
                        </serviceCredentials>
                    </behavior>
                </serviceBehaviors>
            </behaviors>
            <bindings>
              <wsHttpBinding>
                <binding name="wsHttpEndpointBinding">
                  <security mode="TransportWithMessageCredential">
                    <message clientCredentialType="Certificate" />
                  </security>
                </binding>
              </wsHttpBinding>
            </bindings>      
            <services>
                <service name="SBSWCFServiceHost.Operations" 
                         behaviorConfiguration="ServiceBehavior">
                    <endpoint name="wsHttpEndpoint"
                              address=""
                              binding="wsHttpBinding"
                              bindingConfiguration="wsHttpEndpointBinding"
                              contract="SBSWCFServiceHost.IOperations" >
                        <identity>
                            <dns value="localhost" />
                        </identity>
                    </endpoint>                          
                    <endpoint name="mexHttpEndpoint"
                              address="mex"
                              binding="mexHttpsBinding"
                              contract="IMetadataExchange" >
                    </endpoint>
                    <host>
                        <baseAddresses>
                            <add baseAddress="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/" />
                        </baseAddresses>
                    </host>
                </service>
            </services>
        </system.serviceModel>
    </configuration>

    The client config is as follows:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.serviceModel>
            <behaviors>
                <endpointBehaviors>
                    <behavior name="EndpointBehavior">
                        <clientCredentials>
                            <clientCertificate storeLocation="LocalMachine"
                                               storeName="My"
                                               x509FindType="FindByThumbprint"
                                               findValue="e4c87a961f796be6b6cab59c3760e43ffb6e941d"/>
                        </clientCredentials>
                  </behavior>
                </endpointBehaviors>
            </behaviors>      
            <bindings>
                <wsHttpBinding>
                    <binding name="wsHttpEndpoint" 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="TransportWithMessageCredential">
                            <transport clientCredentialType="None" proxyCredentialType="None"
                                realm="" />
                            <message clientCredentialType="Certificate" negotiateServiceCredential="true"
                                algorithmSuite="Default" />
                        </security>
                    </binding>
                </wsHttpBinding>
            </bindings>
            <client>
              <endpoint address="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/"
                  binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint"
                  contract="SBSWCFService.IOperations" name="wsHttpEndpoint">
                  <identity>
                      <dns value="localhost" />
                  </identity>
              </endpoint>
            </client>
        </system.serviceModel>
    </configuration>

    As mentioned earlier, I have successfully tested some client / server calls using basicHttpBinding.

    The following is a Summary of the tasks I performed, based on the contents of numerous posts and documents.

    1. Created a self-signed CA certificate (named RootCATest) on the server, and placed it in the Trusted Root Certification Authorities Certificates folder of the Local Computer.

    2. Created a certificate which is signed by the RootCATest certificate (named TempCert), on the server, and placed it in the Personal Certificates folder of the Local Computer.

    3. Exported the TempCert certificate and private key.

    4. Copied the TempCert .cer and .pvk files to the client machine, and imported the TempCert Certificate into the Personal Certificates folder of the Local Computer.

    5. Executed  ICalcs.exe [private key path] /grant "NT AUTHORITY\NETWORK SERVICE":R on the server machine, using the path to the private key for the TempCert certificate.

    6. Executed   netsh http add sslcert ipport=0.0.0.0:8003 certhash=[TempCert thumbprint] appid=[{application id}] on the server machine

    I believe I am close to getting this working, yet have not made any progress for some time.

    Any assistance or suggestions will be greatly appreciated.

    Many thanks.

    Tuesday, January 15, 2013 11:30 AM

All replies

  • I hope the following URl wil help you to slove the problem.

    http://www.codeproject.com/Articles/36683/9-simple-steps-to-enable-X-509-certificates-on-WCF


    With Thanks and Regards
    Sambath Raj.C
    click "Proposed As Answer by" if this post solves your problem or "Vote As Helpful" if a post has been useful to you
    Happy Programming!

    • Proposed as answer by MiniPeter Wednesday, January 16, 2013 8:02 AM
    Tuesday, January 15, 2013 1:24 PM
  • Hi Sambath. I previously found this post on codeproject, and followed it meticulously. Thank you for your suggestion.

    Tuesday, January 15, 2013 7:05 PM
  • After some further experimentation, I have noticed additional behavior.

    Steps taken are as follows:

    I deleted both client and server certificates, and recreated them in accordance with
    ...codeproject.com/Articles/36683/9-simple-steps-to-enable-x-509-certificates-on-wcf

    I added the new sslcert using netsh. I then exported the client certificate from the server and
    imported it into the client store.

    I modified the service app.config with the new certificates info, and started the service.

    I modified the client app.config <endpointBehaviors> as follows:

     <endpointBehaviors>
      <behavior name="EndpointBehavior">
       <clientCredentials>
        <clientCertificate storeLocation="LocalMachine"
               storeName="My"
               x509FindType="FindBySubjectName"
               findValue="WCFClient" />
        <serviceCertificate>
         <authentication certificateValidationMode="PeerTrust" />
        </serviceCertificate>
       </clientCredentials>
       </behavior>
     </endpointBehaviors>

    I updated the Service Reference. The update procedure once again issued a Security Alert as before.

    I then executed the client, and received this error: 
     
    "The client certificate is not provided. Specify a client certificate in ClientCredentials."

    I then set a breakpoint on "client = new WCFService.Client();" and checked the "client" instance.
    The value of client.ClientCredentials.ClientCertificate.Certificate = null.

    I then added the following in code after "client = new WCFService.Client();":

     X509Store store = new X509Store("My", StoreLocation.LocalMachine);
     store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
     X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
     foreach (X509Certificate2 x509 in collection)
     {
      if (x509.Thumbprint == "236D7D4AD95753B8F22D3781D61AACB45518E1B5")
      {
       client.ClientCredentials.ClientCertificate.SetCertificate(
        x509.SubjectName.Name, store.Location, StoreName.My);
      }
     }

    After execution of this code, client.ClientCredentials.ClientCertificate.Certificate contains the certificate.

    When then executing "client.Open();" , an exception is thrown with the following contents.

    The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
    The remote certificate is invalid according to the validation procedure.
    Could not establish trust relationship for the SSL/TLS secure channel with authority

    If anyone with knowledge of what may be happening here could shed some light on this I will be most grateful.

    Friday, January 18, 2013 9:16 AM