I have a WCF self-hosted service that is accessed over a VPN by client applications. This works in most cases, but some clients are unable to find the server by the DNS name. I want to configure it so that the IP address is specified as well. I cannot simply use the server's IP address instead of the server name in the client config because then it fails the security check because the remote endpoint provides a DNS claim of its server name. I could replace the server certificate with one specifiying the IP address as the subject name, but my understanding is that this would not work either.
How can I change the configuration so that the client can find the service by its Ip address while still using the server name for its identity?
Service configuration:
...
<bindings>
<customBinding>
<binding name="gzipBinding">
<gzipMessageEncoding />
<sslStreamSecurity />
<tcpTransport>
</tcpTransport>
</binding>
</customBinding>
<wsHttpBinding>
<binding name="ClientCertAuthenticationBinding">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="MyServices.HandshakeService" behaviorConfiguration="HandshakeServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://10.0.0.4:8000/Handshake"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="ClientCertAuthenticationBinding" contract="OCS.Client.KnownLayer.IHandshaker"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
<behaviors>
<serviceBehaviors>
<behavior name="HandshakeServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
<serviceCredentials>
<serviceCertificate findValue="MyServiceComputerName" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
<clientCertificate>
<!-- <authentication certificateValidationMode="Custom" customCertificateValidatorType="Rdt.CertificateIdentification.ClientAuthentication.MyX509CertificateValidator, OCS"/>-->
<!-- The custom validator replicates the chaintrust functionality and extends it with a check against the identity database-->
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Client configuration:
<system.serviceModel>
<client>
<endpoint address="http://MyServiceComputerName:8000/Handshake" binding="wsHttpBinding" behaviorConfiguration="ClientCertificateBehavior"
bindingConfiguration="WSHttpBinding_IHandshaker" contract="IHandshaker"
name="WSHttpBinding_IHandshaker"/>
</client>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IHandshaker">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<clientCertificate findValue="MyClientCert" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>