Веб-сервис WCF за открытым обратным прокси - PullRequest
8 голосов
/ 08 ноября 2008

Как правильно обслуживать WSDL веб-службы WCF, расположенной в частной локальной сети, из-за обратного прокси-сервера, прослушивающего общедоступный IP-адрес?

У меня есть веб-сервер Apache, настроенный в режиме обратного прокси-сервера, который прослушивает запросы на общедоступный IP-адрес и обслуживает их с внутреннего узла IIS. Веб-служба WCF генерирует WSDL с использованием полного доменного адреса хоста локальной сети, который, разумеется, не может быть прочитан клиентом веб-службы Интернета.

Есть ли какой-либо параметр, который можно настроить в web.config приложения wcf или в IIS, чтобы настроить сгенерированный WSDL, содержащий адрес хоста, и вместо него поставить публичный адрес?

Ответы [ 3 ]

9 голосов
/ 04 июня 2009

К вашему классу обслуживания добавьте атрибут:

<ServiceBehavior(AddressFilterMode:=AddressFilterMode.Any)>

Это позволяет клиенту обращаться к сервису как https: // ..., но сервис должен быть размещен на http: // ..... См. этот ответ , чтобы узнать, как создать расширение, позволяющее указывать AddressFilterMode.Any через конфигурацию без атрибутов кода.

В файле web.config хоста службы элемент конечной точки должен иметь абсолютный URL-адрес в атрибуте адреса, который является общедоступным URL-адресом, который будет использоваться клиентом. В том же элементе конечной точки установите для атрибута listenUri абсолютный URL-адрес, который прослушивает хост службы. Способ определения абсолютного URI по умолчанию, который прослушивает хост, заключается в добавлении ссылки на службу в клиентском приложении, которая указывает на физический сервер, на котором размещена служба. У клиента web.config будет адрес службы. Затем я копирую это в атрибут listenUri в хосте web.config.

В вашей конфигурации поведения сервиса добавьте элемент serviceMetaData с атрибутом httpGetEnabled = true

Так что у вас будет что-то вроде:

<serviceBehaviors>
  <behavior name="myBehavior">
    <serviceMetadata httpGetEnabled="true" />
  </behavior
</serviceBehaviors>
...
<services>
  <service name="NamespaceQualifiedServiceClass" behavior="myBehavior" >
    <endpoint address="https://www.sslloadbalancer.com" binding="someBinding" contract="IMyServiceInterface" listenUri="http://www.servicehost.com" ...  />
  </service>
</services>

Я не уверен, работает ли это с безопасностью сообщений или транспортной безопасностью. Для этого конкретного приложения учетные данные были переданы как часть DataContract, поэтому у нас был базовый режим безопасности HttpBinding = нет. Поскольку транспорт безопасен (для балансировщика нагрузки ssl), проблем с безопасностью не было.

Также можно оставить атрибут listenUri пустым, однако он должен присутствовать.

К сожалению, в WCF есть ошибка, когда базовый адрес импортированных схем в WSDL имеет базовый адрес listenUri, а не публичный базовый адрес (тот, который настроен с использованием атрибута адреса конечной точки). Чтобы обойти эту проблему, вам нужно создать реализацию IWsdlExportExtension, которая напрямую импортирует импортированные схемы в документ WSDL и удаляет импорт. Пример этого приведен здесь http://winterdom.com/2006/10/inlinexsdinwsdlwithwcf. Кроме того, вы можете получить пример класса, наследуемый от BehaviorExtensionElement, и дополнить два новых метода:

Public Overrides ReadOnly Property BehaviorType() As System.Type
    Get
        Return GetType(InlineXsdInWsdlBehavior)
    End Get
End Property

Protected Overrides Function CreateBehavior() As Object
    Return New InlineXsdInWsdlBehavior()
End Function

Это позволит вам добавить поведение расширения в файл .config и добавить поведение, используя конфигурацию, а не создавать фабрику сервисов.

в элемент конфигурации system.servicemodel добавить:

  <endpointBehaviors>
    <behavior name="SSLLoadBalancerBehavior">          
      <flattenXsdImports/>
    </behavior>
  </endpointBehaviors>
        </behaviors>
<extensions>
  <behaviorExtensions>
    <!--The full assembly name must be specified in the type attribute as of WCF 3.5sp1-->
    <add name="flattenXsdImports" type="Org.ServiceModel.Description.FlattenXsdImportsEndpointBehavior, Org.ServiceModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>        
  </behaviorExtensions>
</extensions>

А затем сослаться на новое поведение конечной точки в конфигурации конечной точки с помощью атрибута поведениеConfiguration

<endpoint address="" binding="basicHttpBinding" contract="WCFWsdlFlatten.IService1" behaviorConfiguration="SSLLoadBalancerBehavior">
1 голос
/ 21 января 2009

У меня похожие проблемы, одной из которых было разрешение публичных и серверных адресов. Это решило эту проблему, хотя у меня все еще есть проблемы с аутентификацией.

http://blogs.msdn.com/wenlong/archive/2007/08/02/how-to-change-hostname-in-wsdl-of-an-iis-hosted-service.aspx

0 голосов
/ 30 декабря 2008
...