Howto WCF Service HTTPS Binding and Endpoint Configuration in IIS with Load Balancer?

21,201

Solution 1

I'm answering this as I've been asked by a few people who know that the app is in production, but didn't see an answer here.

We couldn't solve this in the above scenario. HTTPS from the client to the load balancer is OK. The problem is when the load balancer takes that connection and points it to a web server in an unencrypted format. This seemingly breaks the WCF protocol. The client is sending HTTPS communications but the server is getting unencrypted communication.

We solved the issue by passing through all SSL communications.

The best "solution" would be to see if your WCF service was not using the HTTP method of transmission and setting up your load balancer to pass these communications through unaltered. The load balancer could then do its standard operating procedure on regular HTTPS traffic generated from the website.

I haven't tested this as our application scenario requires the WCF service to be compatible with ASP.NET.

Hopefully someone else can elaborate on this with some more information.

Solution 2

I realise this a very old question, but I've come across this issue recently, and solved it using steps provided here:

https://blog.tonysneed.com/2012/06/18/building-scalable-and-secure-wcf-services/

As one of the other responses here state, it requires subclassing HttpTransportElement and its BindingElementType, so that it returns a ISecurityCapabilities that "fools WCF" into thinking the connection is secure. You can then use this tranport element in a customBinding.

Share:
21,201

Related videos on Youtube

Mike G
Author by

Mike G

My name is Mike and I work mostly in the web world doing development on web applications. I do full stack development in with Microsoft technologies. This means I mainly have experience in ASP.NET and MVC.NET. I've worked with C# since 2.0 and am currently developing most projects in 4.5.1. Being a web developer means I have dealt with a lot of client-side frameworks. My current work has me using AngularJS and Bootstrap. I've been doing a lot of work with NodeJS in building our company's internal UI framework with these two technologies. I'm a big proponent with working with LESS. I also do most of our team's build management tasks. I run our Team Foundation Server, Jenkins build server, and Gerrit. On the side I have done some work with Java and other technologies. I have experience working with *nix based systems, both as a user and administering servers.

Updated on September 17, 2022

Comments

  • Mike G
    Mike G over 1 year

    We have a WCF service that is being hosted on a set of 12 machines. There is a load balancer that is a gateway to these machines.

    Now the site is setup as SSL; as in a user accesses it through using an URL with https. I know this much, the URL that addresses the site is https, but none of the servers has a https binding or is setup to require SSL. This leads me to believe that the load balancer handles the https and the connection from the balancer to the servers are unencrypted (this takes place behind the firewall so no biggie there).

    The problem we're having is that when a Silverlight client tries to access a WCF service it is getting a "Not Found" error. I've set up a test site along with our developer machines and have made sure that the bindings and endpoints in the web.config work with the client. It seems to be the case in the production environment that we get this error.

    Is there anything wrong with the following web.config? Should we be setting up how https is handled in a different manner?

    We're at a loss on this currently since I've tried every programmatic solution with endpoints and bindings. None of the solutions I have found deal with a load balancer in the manner we're dealing.

    Web.config service model info:

      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="TradePMR.OMS.Framework.Services.CRM.CRMServiceBehavior">
              <serviceMetadata httpsGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
            <behavior name="TradePMR.OMS.Framework.Services.AccountAggregation.AccountAggregationBehavior">
              <serviceMetadata httpsGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <bindings>          
          <customBinding>    
            <binding name="SecureCRMCustomBinding">
              <binaryMessageEncoding />
              <httpsTransport />
            </binding>
    
            <binding name="SecureAACustomBinding">
              <binaryMessageEncoding />
              <httpsTransport />
            </binding>
          </customBinding>
          <mexHttpsBinding>
            <binding name="SecureMex" />
          </mexHttpsBinding>
        </bindings>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    
        <!--Defines the services to be used in the application-->
        <services>
          <service behaviorConfiguration="TradePMR.OMS.Framework.Services.CRM.CRMServiceBehavior"
            name="TradePMR.OMS.Framework.Services.CRM.CRMService">
    
            <endpoint address="" binding="customBinding" bindingConfiguration="SecureCRMCustomBinding"
              contract="TradePMR.OMS.Framework.Services.CRM.CRMService" name="SecureCRMEndpoint" />
    
            <!--This is required in order to be able to use the "Update Service Reference" in the Silverlight application-->
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
    
          <service behaviorConfiguration="TradePMR.OMS.Framework.Services.AccountAggregation.AccountAggregationBehavior"
            name="TradePMR.OMS.Framework.Services.AccountAggregation.AccountAggregation">
    
            <endpoint address="" binding="customBinding" bindingConfiguration="SecureAACustomBinding"
              contract="TradePMR.OMS.Framework.Services.AccountAggregation.AccountAggregation" name="SecureAAEndpoint" />
    
            <!--This is required in order to be able to use the "Update Service Reference" in the Silverlight application-->
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
      </system.serviceModel>
    </configuration>
    

    The ServiceReferences.ClientConfig looks like this:

    <configuration>
        <system.serviceModel>
            <bindings>
                <customBinding>
                    <binding name="StandardAAEndpoint">
                        <binaryMessageEncoding />
                        <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                    </binding>
                    <binding name="SecureAAEndpoint">
                        <binaryMessageEncoding />
                        <httpsTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                    </binding>
                    <binding name="StandardCRMEndpoint">
                        <binaryMessageEncoding />
                        <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                    </binding>
                    <binding name="SecureCRMEndpoint">
                        <binaryMessageEncoding />
                        <httpsTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                    </binding>
                </customBinding>
            </bindings>
            <client>
                <endpoint address="https://Service2.svc"
                    binding="customBinding" bindingConfiguration="SecureAAEndpoint"
                    contract="AccountAggregationService.AccountAggregation" name="SecureAAEndpoint" />
                <endpoint address="https://Service1.svc"
                    binding="customBinding" bindingConfiguration="SecureCRMEndpoint"
                    contract="CRMService.CRMService" name="SecureCRMEndpoint" />
            </client>
        </system.serviceModel>
    </configuration>
    

    (The addresses are of no consequence since those are dynamically built so that they will point to a dev's machine or to the production server)

  • Admin
    Admin over 11 years
    Can you provide more information on the custom transport?
  • Admin
    Admin almost 11 years
    Thank you for your answer but there's no detail in it
  • Mike G
    Mike G about 6 years
    Thanks for this blog post. I'll have to try this out. Since it is an "old" question I don't have a scenario where I can test it out. When this was applicable we just offloaded our external SSL cert at the load balancer and then use an internally issued SSL cert to go from the load balancer to the endpoint.