Ошибка WCF по протоколу SSL - 404
Хорошо, мне, должно быть, здесь не хватает чего-то совершенно простого, потому что я много дней искал в Интернете и смотрел десятки ответов там, и здесь, на 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:// ...
EDIT: Я понял, что url, показанный для svcutil в файле wsdl, фактически указывал на имя физического поля веб-сервера, а не на правильный домен. Поэтому я просмотрел шаги, показанные в этой публикации в блоге, чтобы обновить SecureBinding веб-сайта в IIS с помощью adsutil script. Теперь файл 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>
Ответы
Ответ 1
Хорошо, я, по-видимому, решил проблему, и я совершенно не знаю, почему и как.
Вот что я сделал.
- Я добавил BRAND NEW EMPTY сервис 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>
Ответ 2
У меня была такая же проблема с моей стороны. Ваш пост помог мне разобраться, в чем проблема. вот мой раздел сервисной модели. Я обнаружил, что ключи были httpsGetEnabled, а затем установили bindingconfiguration. Я надеюсь, что это поможет.
<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>
Ответ 3
Недавно я имел дело с этим и хочу добавить настройку. Если вы выполните приведенные выше инструкции, вы сможете заставить службу работать с 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>
(взято из моей кодовой базы, настраивает поведениеConfiguration и привязка по мере необходимости)
Ответ 4
Я просто потратил несколько часов на это, и оказалось, что моей проблемой было имя службы
<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.
Ответ 5
В моем случае не ответы на эти ответы помогли.
Вместо этого мне нужно добавить дубликат <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>
Я надеюсь, что это может быть полезно кому-то, когда-нибудь.
Ответ 6
У меня была такая же проблема, и я потратил один день на решение этой проблемы. Наконец, ниже конфигурация работала для доступа к 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>
Ответ 7
Все кажется вполне допустимым, никаких вопиющих ошибок вообще...
Только одно наблюдение/вопрос: где находится ваш файл *.svc?
В сообщении об ошибке я вижу:
https://www.mydomain.com/myservice.svc
Является ли ваш файл *.svc действительно в виртуальном каталоге верхнего уровня вашего сайта?
Как правило, файл *.svc находится внутри виртуального каталога в IIS, и поэтому адрес будет выглядеть примерно так:
https://www.mydomain.com/YourVirtualDirectory/myservice.svc
Конечно, вы можете развернуть приложение ASP.NET и файл WCF службы *.svc в корень вашего IIS, но это не очень часто, по моему опыту.
Просто штука, чтобы проверить.....
Марк
Ответ 8
Это не сработало для вас раньше, потому что вы назвали конфигурацию basicHttpBinding "basicHttpBinding", но не ссылались на эту конфигурацию в своем теге с привязкойConfiguration = "basicHttpBinding"
В ваших изменениях, которые работали с добавлением другой конфигурации службы, вы тогда ссылались на конфигурацию привязки, которая содержит node, и поэтому она работает.
Ответ 9
Еще одна вещь, чтобы проверить, встретите ли вы ту же ошибку 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>
Но добавление DID имени пространства имен (ProjectBar):
<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>