Search code examples
wcfweb-servicesbindingsslwcf-binding

Setting up config files for WCF with SSL and certificates


I'm trying to set up a WCF webservice in IIS 7 with SSL and I'm a bit lost with config files. I want the data from the server to the client to be garbled (Is this enough with SSL?) The client will also need to identity itself to the server through a certificate.

I have the following certificates in place:

  • dev.test.com - accessing the url https://dev.test.com/TestService.svc shows that there is this valid certificate in place.
  • TestServer - a dummy certificate that identifies the server (Do I need really need this? Or perhaps I can reuse the dev.test.com? Maybe have server.test.com?)
  • TestClient - a dummy certificate on the client side

And this is how my config files are set up:

Web.config (Server):

<bindings>
  <wsHttpBinding>
    <binding name="wsHttpEndpointBinding"
             messageEncoding="Mtom">
      <security mode="Message">
        <transport clientCredentialType="None" />
        <message clientCredentialType="Certificate" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

<services>
  <service
    name="TestService"
    behaviorConfiguration="TestServiceBehavior">
    <endpoint
      name="TestEndPoint"
      address=""
      binding="wsHttpBinding"
      bindingConfiguration="wsHttpEndpointBinding"
      bindingNamespace="http://www.example.com/"
      contract="iWebService">
      <!--<identity>
        <dns value=""/>
      </identity>-->
    </endpoint>
    <endpoint address="mex" binding="mexHttpsBinding"  bindingConfiguration="" name="MexHttpsBindingEndpoint" contract="IMetadataExchange"/>
  </service>
</services>

<behaviors>
  <serviceBehaviors>
    <behavior name="TestServiceBehavior">
      <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
      <serviceCredentials>
        <clientCertificate>
          <authentication certificateValidationMode="PeerOrChainTrust" />
        </clientCertificate>
        <serviceCertificate findValue="TestServer" storeLocation="LocalMachine"
          storeName="My" x509FindType="FindBySubjectName" />
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>

<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

App.config (Client):

<bindings>
  <wsHttpBinding>
    <binding name="wsHttpBinding" bypassProxyOnLocal="false"
      transactionFlow="false" hostNameComparisonMode="StrongWildcard"
      messageEncoding="Mtom" textEncoding="utf-8" useDefaultWebProxy="true"
      allowCookies="false">
      <reliableSession ordered="true"
        enabled="false" />
      <security mode="Message">
        <transport clientCredentialType="None" proxyCredentialType="None"
          realm="" />
        <message clientCredentialType="Certificate" negotiateServiceCredential="true"
          algorithmSuite="Default" />
      </security>
    </binding>
    <binding name="TestEndPoint" bypassProxyOnLocal="false"
      transactionFlow="false" hostNameComparisonMode="StrongWildcard"
      messageEncoding="Mtom"
      textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
      <reliableSession ordered="true"
        enabled="false" />
      <security mode="Transport">
        <transport clientCredentialType="None" proxyCredentialType="None"
          realm="" />
        <message clientCredentialType="Certificate" negotiateServiceCredential="true" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

<client>
  <endpoint address="https://dev.test.com/TestService.svc"
    behaviorConfiguration="TestServiceBehavior"
    binding="wsHttpBinding" bindingConfiguration="wsHttpBinding"
    contract="IContractName" name="wsHttpBinding">
    <identity>
      <dns value="TestServer" />
    </identity>
  </endpoint>
  <endpoint address="https://dev.test.com/DistributionCenterService.svc"
    binding="wsHttpBinding" bindingConfiguration="TestEndPoint" contract="IContract.Name"
    name="TestEndPoint" />
</client>

<behaviors>
  <endpointBehaviors>
    <behavior name="TestServiceBehavior">
      <clientCredentials>
        <clientCertificate findValue="TestClient"
                           storeName="My"
                           storeLocation="CurrentUser"
                           x509FindType="FindBySubjectName"/>
        <serviceCertificate>
          <authentication
            certificateValidationMode="PeerOrChainTrust"
            revocationMode="NoCheck"
            trustedStoreLocation="CurrentUser"/>
        </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

When I try to access the https://dev.test.com/TestService.svc, I get
Could not find a base address that matches scheme http for the endpoint with binding WSHttpBinding. Registered base address schemes are [https].

Anyway, I'm really lost with what config setting I should be using.


Solution

  • I believe for you to be able to use https, your security mode on the wsHttpBinding for the client needs to be either Transport or (probably in your case) TransportWithMessageCredential.