我们有一个 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>