如何使用负载均衡器在 IIS 中进行 WCF 服务 HTTPS 绑定和端点配置?

如何使用负载均衡器在 IIS 中进行 WCF 服务 HTTPS 绑定和端点配置?

我们有一个 WCF 服务托管在一组 12 台机器上。有一个负载平衡器作为这些机器的网关。

现在,网站已设置为 SSL;用户通过使用带有 https 的 URL 访问网站。我知道,指向网站的 URL 是 https,但没有服务器具有 https 绑定或设置为需要 SSL。这让我相信负载平衡器处理 https,并且从平衡器到服务器的连接未加密(这发生在防火墙后面,所以没什么大不了的)。

我们遇到的问题是,当 Silverlight 客户端尝试访问 WCF 服务时,它会收到“未找到”错误。我已经设置了一个测试站点以及我们的开发人员机器,并确保 web.config 中的绑定和端点与客户端兼容。在生产环境中,我们似乎遇到了此错误。

以下 web.config 有什么问题吗?我们是否应该以不同的方式设置 https 的处理方式?

目前我们对此束手无策,因为我已经尝试了所有带有端点和绑定的编程解决方案。我发现没有一个解决方案能够像我们这样处理负载平衡器。

Web.config 服务模型信息:

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

ServiceReferences.ClientConfig 如下所示:

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

(这些地址并不重要,因为它们是动态构建的,因此它们将指向开发人员的机器或生产服务器)

答案1

我回答这个问题是因为有几个人问过我,他们知道该应用程序正在制作中,但没有在这里看到答案。

在上述情况下,我们无法解决这个问题。从客户端到负载均衡器的 HTTPS 是可以的。问题是当负载均衡器接受该连接并将其指向未加密格式的 Web 服务器时。这似乎破坏了 WCF 协议。客户端正在发送 HTTPS 通信,但服务器正在获取未加密的通信。

我们通过传递所有 SSL 通信解决了这个问题。

最好的“解决方案”是查看您的 WCF 服务是否未使用 HTTP 传输方法,并设置负载均衡器以不加改变地传递这些通信。然后,负载均衡器可以对网站生成的常规 HTTPS 流量执行其标准操作程序。

我没有测试过这个,因为我们的应用场景要求 WCF 服务与 ASP.NET 兼容。

希望其他人可以提供更多信息来详细说明这一点。

答案2

我意识到这是一个非常老的问题,但我最近遇到了这个问题,并使用这里提供的步骤解决了它:

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

正如此处其他回复之一所述,它需要子类化 HttpTransportElement 及其 BindingElementType,以便它返回 ISecurityCapabilities,从而“欺骗 WCF”认为连接是安全的。然后您可以在 customBinding 中使用此传输元素。

答案3

我们遇到了同样的问题,并采用了 Microsoft 开发人员提供的解决方案。该解决方案是创建一个自定义 HttpTransport,以覆盖从负载平衡器到服务器的 SSL 要求。

答案4

在 basicHttpBinding 上将安全模式设置为无允许 WCF Web 服务接收非 SSL 流量。

<bindings>
    <basicHttpBinding>
        <binding>
            <security mode="None"></security>
        </binding>
    </basicHttpBinding>
</bindings>

相关内容