0

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>
Peter Dongan
  • 1,762
  • 12
  • 17

1 Answers1

1

but some clients are unable to find the server by the DNS name

You can resolve this issue by reviewing the Troubleshooting Domain Name System (DNS) issues document.

You can try the following methods, see this post for details

1.) Add the IP to the endpoint address & add a host name with the base IP address like so:

<endpoint
  address="http://xx.xx.xx.xx/ServiceApp/Service.svc"
  binding="basicHttpBinding" contract="IService">
</endpoint>
<host>
  <baseAddresses>
    <add baseAddress="http://xx.xx.xx.xx/ServiceApp/" />
  </baseAddresses>
</host>

2.) If you have a domain name (www.myDomain.com) then add this to the host header in IIS.
3.) Add the IP address & computer name to the clients hosts file (easy fix not always possible to get all of your clients to add this to their host file however)

Lan Huang
  • 613
  • 2
  • 5