Search code examples
c#wcfsslcertificatewshttpbinding

WCF SOAP security negotiation after changing certificate


After I changed self-signed certificate "localhost" (DNS=localhost) to "Cloudflare Origin Certificate" (dns=mydomain.com) I get following error:

SOAP security negotiation with 'http://localhost:8000/MyService.svc' for target 'http://localhost:8000/MyService.svc' failed. See inner exception for more details.

Inner exception:

Either the client credential was invalid or there was an error collecting the client credentials by the SSPI.

What I noticed is after I start up client I get window to enter credentials. Dunno why.

What I did exactly:

  1. Generated certificate request in IIS
  2. Completed certificate on CloudFlare
  3. Received key pasted into text file with CloudFlare Root CA
  4. Completed certificate in IIS (Personal, LocalMachine)
  5. In MMC added to Trusted Publishers CloudFlare Root CA (LocalMachine)
  6. For WCF website changed SSL certificate to CloudFlare
  7. Changed in client value from "localhost" to "mydomain.com"
  8. Changed in server value from "localhost" to "mydomain.com"
  9. Changed findValue for

WCF web.config

<system.serviceModel>
    <client />
    <behaviors>
      <serviceBehaviors>
        <behavior name="authBehavior">
          <serviceAuthorization principalPermissionMode="UseWindowsGroups">
            <authorizationPolicies>
              <add policyType="WCF.Common.AuthorizationPolicy, WCF" />
            </authorizationPolicies>
          </serviceAuthorization>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCF.Common.IdentityValidator, WCF" />
            <serviceCertificate findValue="CloudFlare Origin Certificate" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" />
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
        <behavior name="svcBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <basicHttpsBinding>
        <binding name="basicHttpsEndpointBinding" maxReceivedMessageSize="1073741824" maxBufferSize="1073741824" maxBufferPoolSize="1073741824">
          <readerQuotas maxDepth="32" maxArrayLength="1073741824" maxStringContentLength="1073741824" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" />
          </security>
        </binding>
      </basicHttpsBinding>
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding"></binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="WCF.MyService" behaviorConfiguration="svcBehavior">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="WCF.IMyService">
          <identity>
            <dns value="mydomain.com" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

Client app.config

<system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="MessageAndUserName">
                    <security mode="Message">
                        <message clientCredentialType="UserName" />
                    </security>
                </binding>
                <binding name="WSHttpBinding_IMyService" />
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8777/MyService.svc"
                binding="wsHttpBinding" contract="WCF.IMyService"
                name="WSHttpBinding_IMyService">
                <identity>
                    <dns value="mydomain.com" />
                </identity>
            </endpoint>
        </client>

      <behaviors>  
        <serviceBehaviors>  
          <behavior name="DefaultServiceBehavior">  
            <serviceMetadata httpGetEnabled="true" />  
            <serviceDebug includeExceptionDetailInFaults="true" />  
          </behavior>  
        </serviceBehaviors>  
      </behaviors>  
    </system.serviceModel>

I host addional services in my WCF and also I host some services in Client but none of them are needed.

I use wsHttpBindings between WCF and Client. What can I do to get rid of this error?

What is purpose of ussing wsHttpBinding etc...: Allow only this Client to communicate with MyService.. no one else will be allowed. Client app will run on multiple computers in domain. Do you suggest ussing different approach?

Thanks for any idea!

EDIT: Computer with error is not running in domain. Neither work for computer in domain :/

EDIT2: Security mode transport WCF web.config bindings:

<wsHttpBinding>
        <binding name="wsHttpEndpointBinding">
          <security mode="Transport">
            <message clientCredentialType="None" />
          </security>
        </binding>
      </wsHttpBinding>

Client side config bindings:

<bindings>
            <wsHttpBinding>
              <binding name="WSHttpBinding_IMyService">
                <security mode="Transport">
                  <message clientCredentialType="None" />
                </security>
              </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://localhost:8001/MyService.svc"
                binding="wsHttpBinding" contract="WCF.IMyService"
                name="WSHttpBinding_IMyService">
                <identity>
                    <dns value="mydomain.com" />
                </identity>
            </endpoint>
        </client>

IIS: Certificate


Solution

  • Here a few resources to review to help determine if NetTcpBinding would work for you, it sounds like it would since you are consuming the web service internally.

    NetTcpBinding netTcpBinding is best when WCF service and its clients are in intranet infrastructure. As it supports only TCP protocol and not HTTP, so service cannot be accessed over internet.

    This is secure binding is used to send binary encoded SOAP messages with in intranet computers. It supports reliability, transaction and security. If your using netTcpBinding and host WCF service in IIS, you need to make some settings on system and IIS this article will help you for required settings.

    A few tips for troubleshooting related issues:

    • Double click on the cert in MMC does it give you any error messages under the Certificate Information header?
    • Are you able to browse the service from your client in a browser?
    • Is the cert assigned in IIS
    • Do you have the correct binding
    • Is the client using the same binding as the service host?
    • Does your endpoint reference the correct binding and service behavior

    Additional helpful information about NetTcpBinding:

    https://stackoverflow.com/a/3375161/2016162