在负载均衡器和 SSL 后面配置 WCF

Posted

技术标签:

【中文标题】在负载均衡器和 SSL 后面配置 WCF【英文标题】:Configuring WCF behind a load balancer and SSL 【发布时间】:2016-04-17 15:03:52 【问题描述】:

这个问题的变体已经被问遍了,通过这些问题,我已经能够获得 90% 的配置,但我仍然遇到一些问题。我的设置如下所示:

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

我已经指定了

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

我已将 httpGetEnabled 设置为 false 并将 httpsGetEnabled 设置为 true。结果是,当我导航到 https://externaldomain 时,我看到了默认服务屏幕,它显示了正确的 URL,例如svcutilhttps://externaldomain/svc.cs?wsdl

我有两个问题:

    如果我尝试导航到https://externaldomain/svc.cs?wsdl,则不会显示 WSDL,而是将我重定向回默认服务屏幕。我仍然可以通过https://externaldomain/svc.cs/mex 在 Visual Studio 中添加对此服务的引用,但我希望 WSDL 也可用。 当我将服务引用添加到 Visual Studio 时,添加到配置的绑定设置为 httpTransport,并且端点指向 http 而不是 https。如果我手动将其更改为 https 传输并将端点的 URL 更改为 https,则一切正常。这并不理想。

有人可以指出我需要更改哪些文档来解决这两个问题吗?我的服务的配置如下。

<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>

---------编辑-----------

使用 HTTP 传输进行端点下载的问题对我来说有点“废话”。在我指定的端点绑定中:

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

将此更改为httpsTransport 会使用https 传输添加服务引用,但客户端应用程序随后无法到达端点。由于负载均衡器通过 http 进行通信,因此传输必须保持 http。我可以使用 https 绑定指定第二个端点,但这很麻烦。

我仍然没有弄清楚 wsdl 的问题。

【问题讨论】:

那么你的问题到底是什么?如何为 WCF 服务配置 SSL? 此问题应获得“ASCII 模式艺术家”徽章 我刚刚注意到,您的负载均衡器是https。但是网络服务器是http。你打算用什么样的路由方式? @KosalaW 负载均衡器是终止 SSL 的 F5。我认为基础架构人员将其设置为这样,因此证书不需要位于所有 Web 服务器上。 您是否与基础设施人员核对,以便在 F5 中编写 iRules 以保持方案为 https,即使 SSL 已卸载,以便 https 在您的应用程序的 url 中保持一致? 【参考方案1】:

我过去做过类似的事情。我有一个基于 sql 的路由表来选择“路由到”(R2)服务器(webserver1,webserver2)。因此,我的负载均衡器获取消息,然后根据消息中的某些值选择 R2 服务器并将其(调用 R2 上的 Web 服务)传递到 R2 服务器。

SOAP 在消息头中维护安全信息。 (https://msdn.microsoft.com/en-us/library/ms951257.aspx)。所以我所做的是,一旦消息到达负载均衡器,我创建了一个新的消息实例,并将传入消息中的所有属性分配给新消息。这意味着新消息与传入消息的标头不同。这意味着我们应该能够将新消息发送到 http。

R2 服务器处理消息并将确认发送回负载平衡器。最后负载均衡器将确认传递给客户端。需要注意的最重要的一点是负载均衡器和 R2 服务器应该具有相同的 wsdl。让我们知道你是怎么做的。

【讨论】:

以上是关于在负载均衡器和 SSL 后面配置 WCF的主要内容,如果未能解决你的问题,请参考以下文章

Nginx配置:负载均衡和SSL配置

93.Nginx配置:负载均衡和SSL配置

无需停机即可配置谷歌云负载均衡器和托管 SSL

如何将 AWS 应用程序负载均衡器配置为超过 25 个 SSL 证书限制

Nginx负载均衡,ssl原理,生成ssl密钥对,Nginx配置ssl

如何让 SpringSecurity/Grails 与终止 SSL 的负载均衡器很好地配合使用