Интересная проблема с WCF wsHttpBinding через брандмауэр - PullRequest
5 голосов
/ 12 декабря 2008

У меня есть веб-приложение, развернутое в провайдере интернет-хостинга. Это веб-приложение использует службу WCF, развернутую на сервере IIS, расположенном на сервере приложений моей компании. Чтобы иметь доступ к базе данных компании, сетевые парни разрешили мне выставить эту службу WCF через брандмауэр из соображений безопасности. Диаграмма будет выглядеть следующим образом.

[Размещенная страница] ---> (Интернет) ---> | Брандмауэр <Public IP>:<Port-X > | ---> [IIS с сервисом WCF <Comp. Network Ip>:<Port-Y>]

Я также хотел использовать wsHttpBinding, чтобы воспользоваться его функциями безопасности и шифровать важную информацию.

После попытки я получаю следующую ошибку:

Сведения об исключении: System.ServiceModel.EndpointNotFoundException: сообщение с To 'http://:/service/WCFService.svc' не может быть обработано в получателе, из-за несоответствия AddressFilter в EndpointDispatcher. Проверьте, что отправитель и получатель Конечная точкаАдреса согласны.

Проведя некоторые исследования, я обнаружил, что wsHttpBinding использует стандарты WS-Addressing, и, прочитав об этом стандарте, я узнал, что заголовок SOAP расширен и включает такие теги, как «MessageID», «ReplyTo», «Action» и «To».

Так что я предполагаю, что, поскольку конечная точка клиентского приложения указывает IP-адрес и порт брандмауэра, а служба отвечает своим внутренним сетевым адресом, который отличается от IP-адреса брандмауэра, то WS-Addressing запускает указанное выше сообщение. Который я думаю, что это очень хорошая мера безопасности, но она не совсем полезна в моем сценарии.

Цитирование стандартной отправки WS-Addressing (http://www.w3.org/Submission/ws-addressing/)

"Из-за широкого спектра сетевых технологий, широко используемых в настоящее время (например, NAT, DHCP, межсетевые экраны), многие развертывания не могут назначить значимый глобальный URI для данной конечной точки. Чтобы позволить этим «анонимным» конечные точки для инициирования шаблонов обмена сообщениями и получения ответов, WS-Addressing определяет следующий известный URI для использования конечные точки, которые не могут иметь стабильный, разрешимый URI. http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"

КАК настроить свою конечную точку wsHttpBinding для адресации IP-адреса моего брандмауэра и игнорирования или обхода адреса, указанного в теге WS-Addressing «Кому» в заголовке сообщения SOAP? Или мне нужно что-то изменить в конфигурации моей конечной точки сервиса?

Помощь и руководство будут высоко оценены.

Марко.

P.S .: Хотя я нахожу какое-либо решение для этого, я использую basicHttpBinding, конечно, без проблем.

Ответы [ 3 ]

6 голосов
/ 12 декабря 2008

Вы можете попробовать украсить свой класс обслуживания с помощью:

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
4 голосов
/ 15 марта 2010

Более безопасный способ справиться с этим - установить конечную точку ListenUri для URL-адреса службы, а адрес конечной точки - для внешней конечной точки, куда клиенты отправляют сообщения. Таким образом, служба «доверяет» сообщениям, направленным только на этот адрес, а не просто на ЛЮБОЙ адрес.

2 голосов
/ 12 декабря 2008

Я не знаю о решении от Митча Бейкера, никогда не пробовал. Но это включает в себя изменение сгенерированного кода. Есть еще один способ обойти это.

Я предполагаю, что вы сгенерировали клиентский код, используя svcutil.exe, указав MEX-адрес, указывающий на брандмауэр. Когда вы делаете это, вся необходимая конфигурация добавляется в App.config (или Web.config). Однако адрес службы в конфигурации будет указывать на реальный адрес службы (как и в файле WSDL, адрес служебного порога будет адресом реальной службы).

Итак, что я думаю, решит эту проблему:

  1. Сгенерируйте код клиента, указав адрес MEX (например: http://:Port -X / service / wcfservice.svc? Wsdl). Будет сгенерирована вся необходимая конфигурация.

  2. При вызове конструктора клиента укажите URI брандмауэра в качестве EnpointAddress и имя конфигурации сгенерированной конфигурации. Таким образом, клиент отправит сообщение, как если бы оно отправляло его службе, но на адрес брандмауэра:

    client = новый ServiceClient (endpointConfigName, новый System.ServiceModel.EndpointAddress ("http://:Port -X / service / wcfservice.svc"));

...