6
votes

Variations of this question have been asked all over SO, and through those questions I have been able to get my configuration 90% of the way, but I am still having some problems. My setup looks like this:

                                (http://server1)
                                 ----------------
                            -->  -- webserver1 --
                           /     ----------------
                          /
 (https://externaldomain)/
 ---------------------- /
 --- load balancer ---- 
 ---------------------- \
                         \
                          \
                           \     (http://server2)
                            -->  ----------------
                                 -- webserver2 --
                                 ----------------

I have specified

 <useRequestHeadersForMetadataAddress>
    <defaultPorts>
      <add scheme="https" port="443" />
    </defaultPorts>
  </useRequestHeadersForMetadataAddress>

and I have set httpGetEnabled to false and httpsGetEnabled to true. The result is that when I navigate to https://externaldomain I see the default service screen and it displays the correct URLs e.g. svcutil https://externaldomain/svc.cs?wsdl

I have two problems:

  1. If I try to navigate to https://externaldomain/svc.cs?wsdl the WSDL is not shown, instead I get redirected back to the default service screen. I am still able to add a reference to this service in Visual Studio via: https://externaldomain/svc.cs/mex, but I would like the WSDL to be available as well.
  2. When I add the service reference to Visual Studio, the binding that gets added to the config is setup as an httpTransport and the endpoint points at http and not https. If I manually change this to an https transport and change the URL to https for the endpoint everything works fine. This isn't ideal.

Can someone point me in the direction of some documentation on what I need to change to resolve these two problems? The config for my Service is below.

<system.serviceModel>
    <client>
      <endpoint address="http://internalService" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMessageProcessing" contract="IMessageProcessing" name="BasicHttpBinding_IMessageProcessing" />
    </client>
    <services>
      <service behaviorConfiguration="ProcessBehavior" name="Service">
        <host>
          <baseAddresses>
            <add baseAddress="https://externaldomain/Service.svc" />
          </baseAddresses>
        </host>
        <endpoint binding="customBinding" bindingConfiguration="CompressionBinding" name="CompressionBindingEndpoint" contract="IService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ProcessBehavior">
          <serviceThrottling maxConcurrentCalls="100" />
          <serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<useRequestHeadersForMetadataAddress>
        <defaultPorts>
          <add scheme="https" port="443" />
        </defaultPorts>
      </useRequestHeadersForMetadataAddress>
          <serviceDebug includeExceptionDetailInFaults="true" />
          <!--<serviceThrottling maxConcurrentCalls="200"/>-->
        </behavior>
        <behavior name="metadataSupport">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IMessageProcessing" />
      </basicHttpBinding>
      <customBinding>
        <binding name="CompressionBinding" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:15:00" sendTimeout="01:30:00">
          <binaryMessageEncoding compressionFormat="GZip" />
          <httpTransport maxReceivedMessageSize="2147483600" decompressionEnabled="true" />
        </binding>
      </customBinding>
    </bindings>
  </system.serviceModel>

---------EDIT-----------

The issue with the endpoint downloading with an HTTP transport was kind of a 'duh' on my part. In the binding for the endpoint I specify:

<httpTransport maxReceivedMessageSize="2147483600" decompressionEnabled="true" />

Changing this to httpsTransport adds the service reference with an https transport, but the client application is then unable to reach the endpoint. Since the load balancer is communicating via http the transport has to remain http. I could specific a second endpoint with an https binding but that is messy.

I still haven't figured out the wsdl issue though.

1
So what exactly is your problem? How to configure SSL for WCF service?Kosala W
This question should get a "ASCII schema artist" badgeThe_Black_Smurf
I just noticed, your load balancer is https. But the web servers are http. What kind of routing method are you going to use?Kosala W
@KosalaW The load balancer is an F5 that terminates the SSL. I think the infrastructure guys set it up like this so that the cert doesn't need to be on all of the web servers.dparsons
Did you check with the infrastructure guys to write iRules in F5 to keep the scheme as https even though the SSL is offloaded so that https remains consistent in the url at your application?user1145404

1 Answers

0
votes

I have done something similar in the past. I had a sql based routing table to pick "route to"(R2) server (webserver1, webserver2). So my load balancer picks up the message and then selects a R2 server based on some values in the message and passes it (calls a web service on R2) on to R2 server.

SOAP maintains security information in the message header. (https://msdn.microsoft.com/en-us/library/ms951257.aspx). So what I did was once the message arrives at the load balancer, I created a new instance of the message and assigned all properties from the incoming message to new message. That means the new message will not have the same headers as incoming message. Which means we should be able to send the new message to http.

R2 server processes the message and sends an acknowledgement back to load balancer. Finally load balancer passes on the acknowledgement to the client. The most important point to note is load balancer and R2 server should have the same wsdl. Let us know how you go with this.