WCF через SSL - ошибка 404 - PullRequest
       33

WCF через SSL - ошибка 404

38 голосов
/ 05 октября 2009

Хорошо, я, должно быть, упускаю что-то совершенно простое здесь, потому что я гуглял несколько дней, и смотрел там десятки ответов, и здесь, на SO, и я просто НЕ МОГУ заставить это работать, независимо от того, что я мы пробовали Служба прекрасно работает, когда вызывается по обычному HTTP.

Вот наши настройки ... у нас есть домен, http://www.mydomain.com. У нас есть сертификат SSL, установленный в этом домене от thawte, как если бы мы защищали сайт электронной коммерции. Это все работает нормально, и я могу перейти на http s : //www.mydomain.com, и это работает правильно. Я использую сайт VS2008, .NET 3.5 на Windows Server 2003 R2.

Теперь я добавил на свой сайт службу WCF с поддержкой Silverlight, с которой я хочу общаться через SSL. Если я зайду на http s : //www.mydomain.com/myservice.svc, он покажет мне WSDL-описательную страницу " Вы создали службу ", как и ожидалось, которая показывает, чтобы создать свой клиент, используя

svcutil.exe https:// ... 

РЕДАКТИРОВАТЬ: Я понял, что URL, указанный для svcutil в файле wsdl, на самом деле указывает на имя физического ящика веб-сервера, а не на соответствующий домен. Итак, я прошел шаги, показанные в этой публикации блога , чтобы обновить SecureBinding сайта в IIS с помощью сценария adsutil. Теперь файл wsdl показывает правильный адрес SSL, но я все еще получаю ту же ошибку.

Теперь я пошел и попытался подключить к нему мое приложение Silverlight, и оно не работает, возвращая исключение в результате асинхронных вызовов с сообщением " Удаленный сервер возвратил ошибку: NotFound В ряде блогов, которые я читал, говорилось о том, чтобы сузить его до проблем с Silverlight, создав тестовое приложение для Windows и пытаясь ссылаться на него из этого. Ну, я делал это и даже в обычном приложении для Windows, пытаясь получить доступ к службе. по SSL я получаю исключение, заявляющее:

System.ServiceModel.EndpointNotFoundException: 
There was no endpoint listening at https://www.mydomain.com/mysubdir/myservice.svc that could accept the message. 
This is often caused by an incorrect address or SOAP action. 
See InnerException, if present, for more details. ---> 
System.Net.WebException: The remote server returned an error: (404) Not Found.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

Это несмотря на то, что я явно добавил ссылку на службу в приложение Windows, используя схему HTTPS, и она правильно получает все методы и показывает их в Intellisense в редакторе.

Обратите внимание, что это сервис, который НЕ требует явного входа со стороны пользователя. Я собираюсь отправлять пользовательские заголовки в моих конвертах SOAP, чтобы убедиться, что запросы поступают от нашего приложения, и я просто хочу, чтобы хищники не вынюхивали строку и не выбирали пользовательские заголовки.

Теперь к коду, где у меня просто должна быть какая-то глупая маленькая настройка, потому что из всего, что я прочитал, это должно быть довольно простым упражнением.

Во-первых, класс кода службы в моем сервисе имеет следующие атрибуты:

<ServiceBehavior(AddressFilterMode:=AddressFilterMode.Any)> 
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>

Раздел ServiceModel моего web.config на сервере выглядит так:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="basicHttpBinding">
                <security mode="Transport">
                    <transport clientCredentialType ="None"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="standingsBehavior">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="false"/>
                </behavior>
            </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
        <baseAddressPrefixFilters>
            <add prefix="http://www.mydomain.com:80"/>
        </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    <services>
        <service behaviorConfiguration="standingsBehavior" name="lijslwebdata">
            <endpoint address="" binding="basicHttpBinding" contract="lijslwebdata"/>
            <!--<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>-->
        </service>
    </services>
</system.serviceModel>

А раздел ServiceModel app.config в моем приложении для Windows выглядит следующим образом:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_lijslwebdata" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" 
                sendTimeout="00:01:00" allowCookies="false" 
                bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize="65536" maxBufferPoolSize="524288" 
                maxReceivedMessageSize="65536" messageEncoding="Text" 
                textEncoding="utf-8" transferMode="Buffered"
                useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192"
                    maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <security mode="Transport">
                    <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://www.mydomain.com/mysubdir/myservice.svc"
            binding="basicHttpBinding" 
            bindingConfiguration="BasicHttpBinding_lijslwebdata"
            contract="xdata.lijslwebdata" name="BasicHttpBinding_lijslwebdata" />
    </client>
</system.serviceModel>

Ответы [ 10 ]

27 голосов
/ 12 ноября 2009

У меня была такая же проблема на моем конце. Ваш пост помог мне понять, в чем проблема. вот мой раздел модели сервиса. Я обнаружил, что ключами были httpsGetEnabled , а затем настройка привязки Надеюсь, это поможет.

<system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="RequestImageBehavior">
                    <serviceMetadata **httpsGetEnabled**="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                  <dataContractSerializer maxItemsInObjectGraph="1073741824" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service behaviorConfiguration="RequestImageBehavior" name="RequestImage">
                <endpoint address="" 
                          binding="wsHttpBinding" 
                          **bindingConfiguration**="HttpsBinding"
                          contract="IRequestImage">
                </endpoint>
                <endpoint address="mex" 
                          binding="mexHttpBinding" 
                          contract="IMetadataExchange" />
            </service>
        </services>
      <bindings>
        **<wsHttpBinding>
          <binding name="HttpsBinding">
            <security mode="Transport">
              <transport clientCredentialType="None"/>
            </security>
          </binding>
        </wsHttpBinding>**
      </bindings>
    </system.serviceModel>
11 голосов
/ 07 июля 2010

Я имел дело с этим недавно и хочу добавить твик. Если вы будете следовать приведенным выше инструкциям, вы сможете настроить службу для работы с HTTPS, но не одновременно работать как с HTTP, так и с HTTPS. Для этого необходимо иметь два узла конфигурации конечных точек, по одному для каждого протокола, следующим образом:

 <service name="MyCompany.MyService" >
    <endpoint address="" behaviorConfiguration="AspNetAjaxBehavior"
      binding="webHttpBinding" contract="MyCompany.MyService" bindingConfiguration="sslBinding" />
    <endpoint address="" behaviorConfiguration="AspNetAjaxBehavior"
      binding="webHttpBinding" contract="MyCompany.MyService" />
  </service>

(взято из моей кодовой базы, настройте поведенческую конфигурацию и привязку соответствующим образом)

8 голосов
/ 10 октября 2012

Я просто потратил несколько часов на это, и оказалось, что моей проблемой было имя службы

<services>
      <service name="TimberMill.Web.Data.LogReceiverService">
        <endpoint binding="basicHttpBinding" bindingConfiguration="basicBinding"
                     contract="NLog.LogReceiverService.ILogReceiverServer" />
      </service>
    </services>

должен был точно соответствовать аналогичной записи в моем * .svc файле.

<%@ ServiceHost 
    Language="C#" 
    Debug="true" 
    Service="TimberMill.Web.Data.LogReceiverService, TimberMill.Web"
    Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf"
    CodeBehind="LogReceiverService.svc.cs" 
%>

Я не уверен, было ли это связано с моим использованием Autofac. Все работало нормально под простым HTTP. Не удалось под HTTPS.

Ну, я так думаю, я не хочу сейчас что-либо беспокоить, проводя более подробные тесты, чтобы я не разозлил богов WCF-Config и моя конфигурация снова сломалась. YMMV.

3 голосов
/ 08 ноября 2015

В моем случае ни один из этих ответов не помог.

Вместо этого мне нужно было добавить дубликат раздела <binding>, для которого не установлен атрибут name .

Вот дамп соответствующего раздела файла web.config моего сервиса:

<behaviors>
    <serviceBehaviors>
        <behavior name="ServiceBehaviour">
            <serviceMetadata 
                httpsGetEnabled="true" 
                httpsGetUrl="RemoteSyncService.svc"
                httpGetBindingConfiguration="bindingConfig" />
            <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
        <behavior name="">
            <serviceMetadata 
                httpsGetEnabled="true" 
                httpsGetUrl="RemoteSyncService.svc" />
            <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
    </serviceBehaviors>
</behaviors>

<bindings>
  <basicHttpBinding>
    <binding name="bindingConfig" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed">
        <security mode="Transport">
          <transport clientCredentialType="None"/>
        </security>
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
    </binding>

    <!-- Add binding with EMPTY/MISSING name, see https://forums.iis.net/t/1178173.aspx -->
    <binding maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed">
        <security mode="Transport">
          <transport clientCredentialType="None"/>
        </security>
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
    </binding>
  </basicHttpBinding>
</bindings>

Надеюсь, это когда-нибудь пригодится кому-нибудь.

2 голосов
/ 09 сентября 2011

У меня была та же проблема, и я потратил один день на ее решение. Наконец ниже конфигурация работала для HTTPS-доступа.

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="basicHttpBinding">
            </binding>
            <binding name="basicHttpsBinding">
                <security mode="Transport">
                    <transport clientCredentialType ="None"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="standingsBehavior">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
        <baseAddressPrefixFilters>
            <add prefix="http://www.mydomain.com/"/>
        </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    <services>
        <service behaviorConfiguration="standingsBehavior" name="lijslwebdata">
            <endpoint address="" binding="basicHttpBinding" contract="lijslwebdata"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
        <service behaviorConfiguration="standingsBehavior" name="sslwebdata">
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="sslwebdata"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
</system.serviceModel>
1 голос
/ 07 мая 2018

Несколько ответов привели меня к перенастройке моего web.config, чтобы он содержал две конечные точки. Я закончил с этим следующим Web.config.

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="basicHttpBinding">
        </binding>
        <binding name="basicHttpsBinding">
          <security mode="Transport">
            <transport clientCredentialType ="None"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="standingsBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
      <baseAddressPrefixFilters>
        <add prefix="http://www.myhost.com"/>
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>

    <services>
      <service behaviorConfiguration="standingsBehavior" name="NameSpace.ClassName">
        <endpoint address="" binding="basicHttpBinding" contract="NameSpace.ContractInterfaceName"/>
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="NameSpace.ContractInterfaceName"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
  </system.serviceModel>
1 голос
/ 06 октября 2009

Хорошо, я, по-видимому, исправил проблему, и я абсолютно не знаю, почему / как.

Вот что я сделал.

  • Я добавил совершенно новую службу WCF с поддержкой Silverlight
  • Затем я обновил web.config, чтобы отразить обе службы
  • Затем я буквально просто скопировал и вставил все о первом сервисе во второй сервис, кроме имени.

Почему это исправлено, я понятия не имею.

FWIW для всех, вот мой новый раздел ServiceModel web.config со вторым сервисом в нем ...

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="basicHttpBinding">
            </binding>
            <binding name="basicHttpsBinding">
                <security mode="Transport">
                    <transport clientCredentialType ="None"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="standingsBehavior">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
        <baseAddressPrefixFilters>
            <add prefix="http://www.mydomain.com/"/>
        </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    <services>
        <service behaviorConfiguration="standingsBehavior" name="lijslwebdata">
            <endpoint address="" binding="basicHttpBinding" contract="lijslwebdata"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
        <service behaviorConfiguration="standingsBehavior" name="sslwebdata">
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="sslwebdata"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
</system.serviceModel>
1 голос
/ 05 октября 2009

Все выглядит вполне корректно, никаких явных ошибок вообще ...

Только одно наблюдение / вопрос: где находится ваш * .svc файл ??

В сообщении об ошибке я вижу:

 https://www.mydomain.com/myservice.svc 

Действительно ли ваш * .svc файл находится в виртуальном каталоге верхнего уровня вашего сайта?

Как правило, файл * .svc находится внутри виртуального каталога в IIS, поэтому адрес будет выглядеть примерно так:

 https://www.mydomain.com/YourVirtualDirectory/myservice.svc 

Конечно, вы можете развернуть приложение ASP.NET и файл службы WCF * .svc в корне IIS - но, по моему опыту, это не очень распространено.

Просто вещь, которую нужно проверить .....

Марк

0 голосов
/ 05 августа 2014

Еще одна вещь, чтобы проверить, если вы сталкиваетесь с той же ошибкой 404, что и OP. Я возился со многими вещами, но в конце концов решение сводилось к простому добавлению пространства имен в мой сервис web.config.

Так что старые старые ServiceFoo и IServiceFoo НЕ работали:

  <services>
     <service behaviorConfiguration="quuxBehavior" name="ServiceFoo">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="IServiceFoo"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
     </service>
  </services>

Но добавление пространства имен (ProjectBar) DID работает:

  <services>
     <service behaviorConfiguration="quuxBehavior" name="ProjectBar.ServiceFoo">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="ProjectBar.IServiceFoo"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
     </service>
  </services>
0 голосов
/ 15 июля 2011

Это не сработало для вас раньше, потому что вы назвали свою конфигурацию basicHttpBinding «basicHttpBinding», но не указали эту конфигурацию в своем теге для bindingConfiguration = «basicHttpBinding»

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...