У нас есть служба WCF, которая размещается на 12 машинах. Существует балансировщик нагрузки, который является шлюзом к этим машинам.
Теперь сайт настроен как SSL; как если бы пользователь обращается к нему через URL-адрес с https. Я знаю это хорошо, 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>
(Адреса не имеют значения, поскольку они создаются динамически, так что они будут указывать на машину разработчика или на производственный сервер)
Я отвечаю на этот вопрос, поскольку меня спросили несколько человек, которые знают, что приложение находится в разработке, но не нашли здесь ответа.
Мы не смогли решить эту проблему в описанном выше сценарии. 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», заставляя думать, что соединение является безопасным. Затем вы можете использовать этот элемент транспорта в customBinding.
Мы столкнулись с той же проблемой и выбрали решение, предоставленное разработчиком в Microsoft. Это решение состоит в создании настраиваемого HttpTransport, который отменяет требование наличия SSL от балансировщика нагрузки на сервер.