Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
I created a self-hosted WCF service and client on 2 different development machines on a LAN, and used basicHttpBinding in order to test connectivity and functionality. The tests were successful.
 
My goal is to use wsHttpBinding with TransportWithMessageCredential security, and clientCredentialType certificate.
 
I thus created the following app.config file for the service:
 
<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </clientCertificate>            
            <serviceCertificate findValue="WCFServer" 
                      storeLocation="LocalMachine" 
                      storeName="My" 
                      x509FindType="FindBySubjectName"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
      <binding name="wsHttpEndpointBinding">
        <security mode="TransportWithMessageCredential">
        <message clientCredentialType="Certificate"/>
        </security>
      </binding>
      </wsHttpBinding>
    </bindings>    
    <services>
      <service name="WCFServiceHost.Operations" behaviorConfiguration="ServiceBehavior">
        <endpoint name="wsHttpEndpoint" address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"   contract="WCFServiceHost.IOperations">
        </endpoint>              
        <endpoint name="mexHttpEndpoint" address="mex" binding="mexHttpsBinding" contract="IMetadataExchange">
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="https://10.0.0.103:8003/WCFServiceHost/Operations/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>
 
I created 2 certificates (WCFServer and WCFClient) on the server in accordance with
...codeproject.com/Articles/36683/9-simple-steps-to-enable-x-509-certificates-on-wcf
and exported the WCFClient certificate on the server machine, and imported it on the client machine.
 
I also added the ssl certificate binding on the server machine using netsh.
 
I am able to create an instance of the ServiceHost with Service, with the modified app.config.
 
I created the following app.config for the client:
 
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="EndpointBehavior">
          <clientCredentials>
            <clientCertificate storeLocation="LocalMachine"
                       storeName="My"
                       x509FindType="FindBySubjectName"
                       findValue="WCFClient" />
            <serviceCertificate>
              <authentication certificateValidationMode="PeerTrust" />
            </serviceCertificate>
          </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/WCFServiceHost/Operations/"
          binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint"
          contract="WCFService.IOperations" name="wsHttpEndpoint">
        <identity>
          <dns value="WCFServer" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>
 
I then updated the Service Reference.
The update procedure issued a Security Alert, which is most likely related to the subsequent issue described below, and which I have not been able to resolve.
 
I ignored the Security Alert and continued. The Service Reference was updated.
 
I then executed the client, and received this error:

"The client certificate is not provided. Specify a client certificate in ClientCredentials."
 
After stepping through code, I noticed on "client = new WCFService.Client();" that 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 == "236D7D4AD91234B8F22D3781D61AACB56788E1B5")
	{
		client.ClientCredentials.ClientCertificate.SetCertificate(
			x509.SubjectName.Name, store.Location, StoreName.My);
	}
}
 
After execution of this code, client.ClientCredentials.ClientCertificate.Certificate contains the certificate.
 
Upon 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 how I may approach resolution of the above issues can assist, I will be most grateful.
 
Thank you, Ol.
Posted 18-Jan-13 0:59am
OlDevel206

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Well, it's a bit late but establishSecurityContext="true" might be the solution.
  Permalink  
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 489
1 ChintanShukla 295
2 Gihan Liyanage 250
3 Richard Deeming 250
4 RyanDev 250
0 Sergey Alexandrovich Kryukov 8,906
1 OriginalGriff 7,601
2 CPallini 2,603
3 Richard MacCutchan 2,121
4 Abhinav S 1,923


Advertise | Privacy | Mobile
Web03 | 2.8.140827.1 | Last Updated 26 Nov 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100