1

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

user1085907
  • 1,009
  • 2
  • 16
  • 40
  • If you 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? If that is a wildcard cert (*.mydomain) then you have to access your service from from a url that has the domain, you can emulate that locally by messing around with your hosts file. – Popo Dec 12 '18 at 20:28
  • @Popo cert status is "This certificate is OK." and I checked it via C# in another app if its valid. Cert is verified for local computer. I am able to browse service from client browser. It is not wildcart cert it is exactly without www just "mydomain.com". – user1085907 Dec 12 '18 at 20:51
  • looks like you may need to update your wsHttpBinding on both the host and client to use `mode="TransportWithMessageCredential"` since your assigning the cert in IIS it will expect it to be HTTPS. You may also need to assign the cert in the client for the message. Your using a customUserNamePasswordValidator and a cert for credentials based on what your service behavior shows. – Popo Dec 12 '18 at 22:04
  • @Popo ok I will try to use that mode. Anyway I dont use customUserNamePasswordValidator.. that's different behavior! – user1085907 Dec 12 '18 at 22:08
  • ah, your right, in that case, you probably just need to use something like ` ` – Popo Dec 12 '18 at 22:20
  • @Popo ok I set it like this. I also changed due Transport mode client endpoind to use "https" but I get dunno why error "The provided URI scheme 'https' is invalid; expected 'http'" – user1085907 Dec 12 '18 at 22:30
  • did you assign the cert to an https binding in IIS for your service, or are just trying to go over http and use the cert as an identity? `mode="Transport"` is for https, `` no security and over http. Your bindings have to match for both client and host. – Popo Dec 12 '18 at 22:38
  • @Popo yes I did assign it in IIS. Double checked that. I use security mode Trasnport as you mentioned. Bindings are matching.. I will edit my main post to show you my actual bindings and give u screen from IIS – user1085907 Dec 12 '18 at 22:47
  • are you still getting the same error? – Popo Dec 12 '18 at 23:04
  • @Pepo yes it keeping saying that https is invalid – user1085907 Dec 12 '18 at 23:17
  • you are missing the `bindingConfiguration="WSHttpBinding_IMyService"` in your client config. you can browse the service though right? – Popo Dec 12 '18 at 23:38
  • Yea I could browse it. I added missing bindingConfiguration and now I am getting "Could not establish trust relationship for the SSL/TLS secure channel with authority " with innerException "AuthenticationException: The remote certificate is invalid according to the validation procedure". I guess something is wrong with certificate – user1085907 Dec 13 '18 at 10:17
  • I guess its problem because certificate is valid for DNS=mydomain.com not to localhost. – user1085907 Dec 13 '18 at 10:19
  • Well I think I made it all wrong. I want to use wsHttpBinding but I should not use because I want to use IP address instead dns because I cant run in browser https://mydomain:8001. What should I use instead dns certificate for internal purposes? – user1085907 Dec 13 '18 at 10:35
  • I should go TCP binding if my scenario is WCF to service application in same internal network. Is that correct? – user1085907 Dec 13 '18 at 11:02
  • netTcpBinding would be fine for what you are trying to do. – Popo Dec 13 '18 at 15:46
  • Okay.. anyway I still need certificate or dont? If service is going to be internal can I use self-signed certificate? And how certificate works without DNS? I would like to use IP – user1085907 Dec 13 '18 at 16:22
  • You might want to review this article: http://dotnetmentors.com/wcf/when-to-use-which-binding-in-wcf.aspx and this SO answer: https://stackoverflow.com/questions/2536522/wcf-nettcpbinding-security-how-does-it-work – Popo Dec 13 '18 at 17:09
  • I read it, discovered I can use Windows clientCredentialType. Works perfectly on localhost but both WCF and client are run by same user. Can I allow WCF (user A) to get call from Client (user B)? – user1085907 Dec 13 '18 at 18:52
  • I am not sure how to do that locally, we use a dev server to set up/deploy our services/sites for testing. – Popo Dec 13 '18 at 19:03
  • Oh solved by using wcfClient.ClientCredentials.Windows.ClientCredential.UserName. If u want to write post as answer I will accept it :) Many thanks for help! – user1085907 Dec 13 '18 at 19:56
  • glad to hear you got if figured out, hope I did not lead you too far astray. I will keep a note about `wcfClient.ClientCredentials.Windows.ClientCredential.UserName` in case I have to do the same in the future. – Popo Dec 13 '18 at 23:00

1 Answers1

1

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

Popo
  • 2,402
  • 5
  • 33
  • 55