Веб-сервис WCF за общедоступным обратным прокси-сервером

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

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

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


person Robert Mircea    schedule 08.11.2008    source источник


Ответы (3)


Добавьте в свой класс обслуживания следующий атрибут:

<ServiceBehavior(AddressFilterMode:=AddressFilterMode.Any)>

Это позволяет клиенту обращаться к службе как https://..., но служба по-прежнему может размещаться на http://.....

См. Мой ответ на Как указать AddressFilterMode.Any декларативно, чтобы узнать, как создать расширение, позволяющее указывать AddressFilterMode.Any в конфигурации без необходимости атрибуты кода.

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

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

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

У вас будет что-то вроде этого:

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

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

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

К сожалению, в WCF есть ошибка, при которой базовый адрес импортированных схем в WSDL имеет базовый адрес listenUri, а не общедоступный базовый адрес (тот, который настроен с использованием атрибута адреса конечной точки). Чтобы обойти эту проблему, вам необходимо создать реализацию IWsdlExportExtension, которая напрямую переносит импортированные схемы в документ WSDL и удаляет импорт.

Пример этого приведен в этой статье на Встроенный XSD в WSDL с WCF. Кроме того, вы можете унаследовать класс от 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 добавьте:

<behaviors>
  <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>

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

<endpoint address="" binding="basicHttpBinding" contract="WCFWsdlFlatten.IService1" behaviorConfiguration="SSLLoadBalancerBehavior">
person Richard Collette    schedule 03.06.2009
comment
Я просто хочу отметить, что этот ответ основан на WCF 3.5. У меня не было возможности проверить, исправляет ли WCF 4.0 некоторые из этих проблем. Я знаю, что были сделаны некоторые улучшения для лучшей поддержки сценариев обратного прокси. - person Richard Collette; 02.11.2010
comment
Я пробовал это, и он работает, но у него есть несколько проблем: вам придется поместить все свои типы, контракты и привязки в одно и то же пространство имен, и если у вас есть типы с именем FooRequest, вам придется переименовать их, потому что wcf сгенерирует тип с тем же именем. Мне было удобнее вручную редактировать файлы wsdl, иначе пользователям моего сервиса пришлось бы менять свой код. - person Dutch Nico; 30.05.2011
comment
@Dutch. В моем решении обычно есть проект бизнес-объекта и проект службы, каждый из которых имеет разные пространства имен (например, org.app.bo и org.app.servicemodel). Данные из бизнес-объектов копируются в служебные объекты и наоборот. Я использую интерфейсы, определенные в сервисном проекте, для определения контрактов (org.app.servicemodel.ISomeService). Методы службы обычно принимают тип org.app.servicemodel.SomethingRequest в качестве параметра и возвращают тип org.app.servicemodel.SomethingResponse. Я не сталкивался с конфликтами имен при использовании этого типа настройки. Вы что-то еще делаете? - person Richard Collette; 02.06.2011
comment
Изначально я использовал отдельные пространства имен xml для своих сообщений, контракта и привязки. Я поместил их в одно и то же пространство имен, потому что встраивание не сработало. После этого изменения я столкнулся с такими конфликтами имен: ссылка - person Dutch Nico; 08.06.2011
comment
Хорошо, теперь я понимаю разницу. Я добавляю свои собственные версионные пространства имен на основе некоторых прочитанных мною передовых практик. Наверное, поэтому я не столкнулся с проблемой использования типов SomethingRequest и SomethingResponse. См. Руководство по управлению версиями blogs.msdn.com/b/craigmcmurtry /archive/2006/07/23/676104.aspx и msdn .microsoft.com / en-us / library / ms733832.aspx. - person Richard Collette; 10.06.2011
comment
Ошибка с импортированным WSDL с неправильным базовым адресом была исправлена ​​в .NET 3.5 SP1 и .NET 4.0. Вы можете использовать следующие элементы конфигурации, чтобы добиться правильного поведения. ‹ServiceBehaviors› ‹имя поведения = ‹name›› ‹useRequestHeadersForMetadataAddress› ‹defaultPorts› ‹добавить схему = http port = 81 /› ‹добавить схему = https port = 444 /› ‹/defaultPorts›/useRequestHeadersForMetadataAddress› ‹‹/behav / serviceBehaviors › - person Richard Collette; 10.10.2011
comment
+1 для. Также можно оставить атрибут listenUri пустым, но он должен присутствовать. Это была моя проблема. - person JamesQMurphy; 02.04.2015

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

См.: Как изменить HostName в WSDL для службы, размещенной в IIS? Автор: Wenlong Dong

архив

person stephenl    schedule 21.01.2009
comment
Боже мой, Стив, огромное спасибо за эту ссылку, последние несколько часов я схожу с ума. - person Piotr Owsiak; 30.03.2010

См.: Подробная адресация WCF станции обслуживания, Аарон Сконнард

архив ссылка

person Nicolas Dorier    schedule 30.12.2008
comment
Похоже, что это содержимое переместилось на msdn.microsoft.com/en-us/magazine /cc163412.aspx. - person JohnW; 09.12.2009