2
votes

I'm trying to secure my WCF service using transport security model. I've successfully deployed my service to AppHarbor. But I'm getting the following exception when I try to access service page:

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

I haven't uploaded any certificates, just using piggyback SSL there. I've downloaded the build and deployed it on my machine. It works fine.

Here is my system.serviceModel section of web.config:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="TransportSecurity">
                <security mode="Transport">
                    <transport clientCredentialType="None"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <services>
        <service behaviorConfiguration="AuthService.AuthServiceBehavior"  name="AuthService.AuthService">
            <host>
                <baseAddresses>
                    <add baseAddress="https://auth.apphb.com/AuthService.svc" />
                </baseAddresses>
            </host>
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="TransportSecurity" contract="AuthService.IAuthService" />
            <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="AuthService.AuthServiceBehavior">
                <serviceMetadata httpsGetEnabled="true"/>        
                <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

I've already tried this Hosting a WCF Web API app on AppHarbor?

Can somebody please explain me what I'm doing wrong?

2

2 Answers

4
votes

This issue frequently appear when you communicate with the wcf web service thru the LB (AppHarbor one of the example of it).

You should know several things about such kind of communications.

1) Communication between yours client application and LB is secured (https is in use). So you should leverage security binding on the client side.

 <basicHttpBinding>
     <binding name="BasicHttpBinding_IAuthService">
         <security mode="Transport">
             <transport clientCredentialType="None" />
         </security>
     </binding> 
 </basicHttpBinding>

2) Communication between LB and web-front uses http, so server binding should be basicHttpBinding without extra configuration.

<endpoint binding="basicHttpBinding" contract="AuthService.IAuthService" />

Summarizing all that stuff we have

Client

<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IAuthService">
                    <security mode="Transport">
                        <transport clientCredentialType="None" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://auth.apphb.com/AuthService.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAuthService"
                contract="AuthService.IAuthService" name="BasicHttpBinding_IAuthService" />
        </client>
    </system.serviceModel>
</configuration>

Server

<system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <protocolMapping>
      <add scheme="http" binding="basicHttpBinding" />
    </protocolMapping>
    <bindings>
      <basicHttpBinding/>
    </bindings>
    <services>
      <service behaviorConfiguration="AuthService.AuthServiceBehavior" name="AuthService.AuthService">
        <endpoint binding="basicHttpBinding" contract="AuthService.IAuthService" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="AuthService.AuthServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
1
votes

Your approach is not going to work right off the bat. This is because SSL is terminated at the load balancers and the app servers see http traffic. You can read more about AppHarbor load balancers here.

You might be able to fool WCF with this module.

There are also some hints in this discussion: http://support.appharbor.com/discussions/problems/829-transportwithmessagecredential-https-ssl