zic10
zic10

Reputation: 2330

Support both HTTP and HTTPS Web.Config WCF Service

I'm running into a configuration problem with my WCF service when trying to support both https and https. Ideally what I'd like is to run http on my dev machine and then publish to azure running https.

I followed these posts to try and run the configuration: http://jayakrishnagudla.blogspot.com/2009/12/configuring-wcf-services-to-work-with.html

How to configure a single WCF Service to have multiple HTTP and HTTPS endpoints?

My Web.Config is as follows:

<system.serviceModel>
    <services>
      <service name="Backend.Services.UserService.UserService" behaviorConfiguration="">

        <endpoint address=""
           binding="webHttpBinding"
           contract="Backend.Services.UserService.IUserService"
           bindingConfiguration="HttpsBinding"
           behaviorConfiguration="Web">

        </endpoint>

        <endpoint address=""
                  binding="webHttpBinding"
                  contract="Backend.Services.UserService.IUserService"
                  bindingConfiguration="HttpBinding"
                  behaviorConfiguration="Web"
                  >

        </endpoint>
      </service>
    </services>
      <bindings>
        <webHttpBinding>
          <binding name ="HttpBinding">
            <security mode="None">
              <transport clientCredentialType="None"/>
            </security>
          </binding>

          <binding name="HttpsBinding">
            <security mode="Transport"/>
          </binding>
        </webHttpBinding>

    </bindings>
    <behaviors>

      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>

      <endpointBehaviors>
        <behavior name="Web">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <protocolMapping>
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

As far as I can tell, this configuration should be correct according to the above links. However, when I build and run this service locally via http I get the following error:

Could not find a base address that matches scheme https for the endpoint with binding WebHttpBinding. Registered base address schemes are [http].

I'm not quite sure where the problem is and assume its a misconfiguration. Any help would be appreciated.

Upvotes: 5

Views: 10945

Answers (3)

symbiont
symbiont

Reputation: 1562

i finally got it working for HTTP & HTTPS, based on Rick Moss' answer. except that i did not leave away the bindingConfiguration off the endpoint, because it caused a no endpoint listening error:

<configuration>
  ...
  <system.serviceModel>
    <services>
      <service name="WcfService1.Service1">
        <endpoint address="" name="ep1" binding="webHttpBinding" bindingConfiguration="ServiceBinding" contract="WcfService1.IService1" behaviorConfiguration="WebBehavior" />
        <endpoint address="" name="ep1" binding="webHttpBinding" bindingConfiguration="ServiceBindingSSL" contract="WcfService1.IService1" behaviorConfiguration="WebBehavior" />
      </service>
    </services>

    <bindings>
      <webHttpBinding>
        <binding name="ServiceBinding" ...>
          <security mode="None">
          </security>
        </binding>
        <binding name="ServiceBindingSSL" ...>
          <security mode="Transport">
            <transport clientCredentialType="None" />
          </security>
        </binding>
      </webHttpBinding>
    </bindings>

    <behaviors>
      <endpointBehaviors>
        <behavior name="WebBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      ...
    </behaviors>

    <protocolMapping>
        <add scheme="http"  binding="basicHttpBinding" bindingConfiguration="ServiceBinding"/>
        <add scheme="https" binding="basicHttpBinding" bindingConfiguration="ServiceBindingSSL"/>      
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

  </system.serviceModel>
  ...
</configuration>

EDIT: this only seems to work with Anonymous authentication in IIS. Enabling Windows Authentication in a different web service under the same website in IIS caused:

Could not find a base address that matches scheme https for the endpoint with binding WebHttpBinding. Registered base address schemes are [http]. 

i hate Web.config files. they're too tightly coupled to IIS

Upvotes: 3

Rich Moss
Rich Moss

Reputation: 2384

I've been trying to do this for days (years actually, but just restarted a few days ago), and the post above pointed me in the right direction with protocolMapping, but you need to specify the bindingConfiguration in the protocolMapping section to make it choose the <security mode=None> or <security mode=Transport>:

<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
  <protocolMapping>
    <add scheme="http"  binding="basicHttpBinding" bindingConfiguration="ServiceBinding"/>
    <add scheme="https" binding="basicHttpBinding" bindingConfiguration="ServiceBindingSSL"/>      
  </protocolMapping>

Leave the bindingConfiguration attribute off of the endpoint - it will be set automatically based on the protocol. Then set up the second binding configuration in your bindings section:

        <basicHttpBinding>
            <binding name="ServiceBinding"  ...>
                <security mode="None">
                </security>
            </binding>
            <binding name="ServiceBindingSSL" ... >
                <security mode="Transport">
                </security>
            </binding>
        </basicHttpBinding>

This technique worked for me. Hope it helps you!

Upvotes: 5

Ross Bush
Ross Bush

Reputation: 15185

Have you looked at the protocol mapping wcf configuration section?

<protocolMapping>
    <add scheme="http" binding="wsHttpBinding"/>
    <add scheme="https" binding="wsHttpBinding"/>      
</protocolMapping>

Edit : I am not sure why you have configured an "https" binding under the webHttpBinding type. Shouldn't you have both http webHttpBinding and wsHttpBinding defined and assigned to your endpoint?

<webHttpBinding>
    <binding name ="HttpBinding">
        <security mode="None">
            <transport clientCredentialType="None"/>
        </security>
    </binding>
</webHttpBinding>

<wsHttpBinding>
    <binding name="wsHttpEndpointBinding">
        <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None" />
            <message clientCredentialType="UserName" />
        </security>
    </binding>
</wsHttpBinding>

Upvotes: 1

Related Questions