Назад | Перейти на главную страницу

Как выполнить привязку HTTPS службы WCF и конфигурацию конечной точки в IIS с балансировщиком нагрузки?

У нас есть служба 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 от балансировщика нагрузки на сервер.