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

dpa*_*ons 5 c# https wcf wsdl web-services

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

                                (http://server1)
                                 ----------------
                            -->  -- webserver1 --
                           /     ----------------
                          /
 (https://externaldomain)/
 ---------------------- /
 --- load balancer ---- 
 ---------------------- \
                         \
                          \
                           \     (http://server2)
                            -->  ----------------
                                 -- webserver2 --
                                 ----------------
Run Code Online (Sandbox Code Playgroud)

我已经指定

 <useRequestHeadersForMetadataAddress>
    <defaultPorts>
      <add scheme="https" port="443" />
    </defaultPorts>
  </useRequestHeadersForMetadataAddress>
Run Code Online (Sandbox Code Playgroud)

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

我有两个问题:

  1. 如果我尝试导航到https://externaldomain/svc.cs?wsdl未显示的 WSDL,则会被重定向回默认服务屏幕。我仍然可以通过以下方式在 Visual Studio 中添加对此服务的引用:https://externaldomain/svc.cs/mex,但我希望 WSDL 也可用。
  2. 当我将服务引用添加到 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>
Run Code Online (Sandbox Code Playgroud)

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

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

<httpTransport maxReceivedMessageSize="2147483600" decompressionEnabled="true" />
Run Code Online (Sandbox Code Playgroud)

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

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

Kos*_*a W 0

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

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

R2 服务器处理该消息并将确认发送回负载均衡器。最后负载均衡器将确认传递给客户端。最需要注意的一点是负载均衡器和 R2 服务器应该具有相同的 wsdl。让我们知道您如何处理这个问题。