Подтвердить что ты не робот

WCF WebService/IIS Хостинг и конфигурация Проблема за брандмауэром

У меня есть простой веб-сервис WCF. Он размещался на IIS на веб-сайте по умолчанию в нашем производственном домене. (локальный адрес: 10.10.20.100)

По умолчанию этот веб-сайт по умолчанию был настроен для "Все неназначенные" IP-адреса в порту 80: однако я заметил, что это вызвало службу WCF для ее создания WSDL с использованием локального имени DNS сервера. то есть все URI в wsdl были

http://myserver.subdomain.domain.com/.../...

Это было нехорошо, так как мне нужно разоблачить эту услугу на сайтах, которые не знают о внутренней среде производственной среды. И этот конкретный сервер не имеет внешнего DNS-имени. Только внешний IP-адрес...

У меня был некоторый успех в изменении настройки в IIS из "Все неназначенные" → "10.10.20.100"

Это заставляет службу генерировать WSDL с URI

http://10.10.20.100/.../...

Это нормально для других машин внутри субдомена и других поддоменов, но здесь я застрял. Внешний IP-адрес серверов (1.2.3.4) отображается через некоторый перевод NAT/PAT, поэтому он явно не установлен в настройках IP-адресов серверов (т.е. Он не отображается в IP-конфигурации)

Итак, если я изменил IP-адрес веб-сайта по умолчанию IIS с "All Unassigned" → "1.2.3.4", как я сделал для внутреннего адреса, тогда служба WCF вернется с...

Неверный запрос (недопустимое имя хоста)

И если я покину IIS, настроенный на внутреннем IP-адресе, и попытаюсь получить доступ к службе через внешний IP-адрес, я получаю

No protocol binding matches the given address 
'http://1.2.3.4/TestService/Service.svc'. Protocol bindings are 
configured at the Site level in IIS or WAS configuration

Есть ли способ заставить IIS/WCF генерировать WSDL URI с внешним IP-адресом, который явно не настроен на сервере?

Кто-то мне поможет, прежде чем я отброшу службы WCF из окна.

4b9b3361

Ответ 1

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

Сообщите мне, если вы не знаете, как это сделать.

Ответ 2

Я мог бы предотвратить насилие ниндзя... если я понимаю вашу проблему... Вы можете вручную указать полный адрес, который служба должна использовать в web.config, в отличие от того, что ServiceHost вам поможет. Вы должны установить базовый адрес своей службы:

 <service behaviorConfiguration="Behaviour1" name="Api.Poll">
    <endpoint address="soap" binding="basicHttpBinding" bindingConfiguration="soapBinding"
      contract="Api.IPoll" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://www.mydomain.com/Api" />
        <add baseAddress="http://10.10.20.30/Api" />
      </baseAddresses>
    </host>
  </service>

Используя этот метод, ваша служба должна принять указанный базовый адрес плюс имя службы с дополнительным адресом конечной точки, если он у вас есть. Кроме того, вам необходимо будет использовать настраиваемый ServiceHostFactory для программного программирования базового адреса. См. Ниже:

    public class ServiceHostFactory : System.ServiceModel.Activation.ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {                        
        ServiceHost host;

        host = new ServiceHost(serviceType, baseAddresses[0]);

        return host;
    }

Наконец, как только вы создадите класс ServiceHostFactory, вы должны подключить его к своей службе, отредактировав разметку в файле .svc:

<%@ ServiceHost Language="C#" Debug="true" Service="Api.Poll" Factory="Api.ServiceHostFactory" CodeBehind="Poll.svc.cs" %>

Ответ 3

Должен ли он быть IP-адресом, а не FQDN? Переключившись на полное доменное имя и установив это в заголовках хоста для сайта, привязка к нему через

cscript //nologo %systemdrive%\inetpub\adminscripts\adsutil.vbs set W3SVC/1/ServerBindings ":80:hostname.example.com"

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

Ответ 4

Здесь вы можете изменить заголовок в IIS7. Также поместите мой web.config для некоторых, если это поможет.

http://www.sslshopper.com/article-ssl-host-headers-in-iis-7.html

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />      
    <customErrors mode="Off"></customErrors>
  </system.web> 
  <system.serviceModel>
    <client/>
    <services>
      <service name="WcfService1.Service1"
behaviorConfiguration="MyServiceTypeBehaviors">
        <host>
        <baseAddresses>
          <add baseAddress="https://pws.sjukra.is/"/>        
        </baseAddresses>
        </host>
        <endpoint address="https://pws.sjukra.is/Service1.svc"
                  listenUri="/" 
        binding="wsHttpBinding"
        contract="WcfService1.IService1"
        bindingConfiguration="myBasicHttpBindingConfig"/>
        <endpoint contract="IMetadataExchange"
   binding="mexHttpsBinding"                   
   address="mex"/>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="myBasicHttpBindingConfig">
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="Windows" />
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyServiceTypeBehaviors">
          <serviceMetadata httpsGetEnabled="true"/>
          <serviceDebug httpsHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
          <serviceCredentials type="System.ServiceModel.Description.ServiceCredentials">
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfService1.Service1,WcfService1"/>
            <serviceCertificate findValue="pws.sjukra.is" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
              <clientCertificate>
                  <authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
              </clientCertificate>            
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"></serviceHostingEnvironment>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

Ответ 5

Несмотря на то, что это старый поток, он действительно помог мне перенести проект из VS Web Developer Express в MonoDevelop, который включал службу WCF.

Веб-приложение запросило интерфейс JavaScript, определенный службой WCF, используя следующий URL-адрес: http://127.0.0.1:8080/path-to-service/service.svc/js, который дал мне ошибку: Нет привязки протокола к указанному адресу

Вдохновленный этим потоком, я смог исправить проблему, потому что работа с сервисом с localhost вместо 127.0.0.1 работала! С запросом http://localhost:8080/path-to-service/service.svc/js Я получил интерфейс JavaScript.

На самом деле мое приложение не использовало абсолютный URL для включения интерфейса JavaScript, однако по умолчанию при запуске приложения из MonoDevelop он будет обращаться к приложению с использованием 127.0.0.1, таким образом, вызов, чтобы включить JavaScript из службы, не удался.

Это все еще не идеально, так как я не смог запустить приложение из MonoDevelop с помощью localhost вместо 127.0.0.1, так как конфигурация для XSP позволяет мне указывать IP-адрес, но по крайней мере я знаю, как получить вокруг него.

Ответ 6

Проблема заключается в том, что после изменения порта или ip-адреса вы запускаете перезапуск пула приложений, который вы используете, потому что он все еще имеет старую информацию до тех пор, пока она не будет скопирована.