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:
="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:
="1.0"="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.