Как подключить HTTPS службы WCF и настроить конечную точку в IIS с балансировщиком нагрузки?
У нас есть служба WCF, которая размещается на 12 машинах. Существует балансировщик нагрузки, который является шлюзом для этих машин.
Теперь сайт настроен как SSL; как пользователь получает доступ к нему через использование URL с https. Я так много знаю, что URL-адрес сайта - https, но ни один из серверов не имеет привязки https или не настроен на использование SSL. Это наводит меня на мысль, что балансировщик нагрузки обрабатывает https, и соединение между балансировщиком и серверами не зашифровано (это происходит за брандмауэром, так что там нет ничего страшного).
Проблема, с которой мы сталкиваемся, заключается в том, что, когда клиент Silverlight пытается получить доступ к службе WCF, он получает ошибку "Not Found". Я создал тестовый сайт вместе с нашими машинами для разработчиков и убедился, что привязки и конечные точки в 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>
(Адреса не имеют никакого значения, так как они создаются динамически, так что они будут указывать на компьютер разработчика или на производственный сервер)
3 ответа
Я отвечаю на это, поскольку меня спросили несколько человек, которые знают, что приложение находится в производстве, но не видели ответа здесь.
Мы не могли решить эту проблему в приведенном выше сценарии. HTTPS от клиента до балансировщика нагрузки в порядке. Проблема в том, что балансировщик нагрузки берет это соединение и указывает его на веб-сервер в незашифрованном формате. Это, по-видимому, нарушает протокол WCF. Клиент отправляет связь HTTPS, но сервер получает незашифрованную связь.
Мы решили проблему, пройдя через все связи SSL.
Лучшим "решением" было бы посмотреть, не использует ли ваша служба WCF метод передачи HTTP, и настроить балансировщик нагрузки для передачи этих сообщений без изменений. Затем балансировщик нагрузки может выполнять свою стандартную рабочую процедуру для обычного HTTPS-трафика, генерируемого с сайта.
Я не проверял это, поскольку наш сценарий приложения требует, чтобы служба WCF была совместима с ASP.NET.
Надеюсь, кто-то еще может уточнить это с некоторой дополнительной информацией.
Я понимаю, что это очень старый вопрос, но недавно я столкнулся с этой проблемой и решил ее, используя приведенные здесь шаги:
https://blog.tonysneed.com/2012/06/18/building-scalable-and-secure-wcf-services/
Как говорится в одном из других ответов, он требует создания подкласса HttpTransportElement и его BindingElementType, чтобы он возвращал ISecurityCapabilities, который "обманывает WCF", заставляя думать, что соединение безопасное. Затем вы можете использовать этот элемент transport в customBinding.
Мы столкнулись с той же проблемой и пошли с решением, предоставленным разработчиком из Microsoft. Это решение заключается в создании пользовательского HttpTransport, который отменяет требование иметь SSL от балансировщика нагрузки к серверу.
Установка для режима безопасности значения None в basicHttpBinding позволяет веб-службам WCF получать трафик, отличный от SSL.
<bindings>
<basicHttpBinding>
<binding>
<security mode="None"></security>
</binding>
</basicHttpBinding>
</bindings>