WCF over SSL - 404错误

时间:2009-10-05 16:37:53

标签: ssl https wcf wcf-binding

好吧,我必须在这里找到一些非常简单的东西,因为我一直在谷歌上搜索,并在那里看了几十个答案,而且在这里,我无法让它工作,无论我是什么我试过了。通过普通HTTP调用时,该服务工作正常。

以下是我们的设置...我们有一个域名http://www.mydomain.com。我们在该域上安装了SSL证书,就像我们保护电子商务网站一样。一切正常,我可以访问http s ://www.mydomain.com,它运作正常。 我在Windows Server 2003 R2上运行VS2008,.NET 3.5站点。

现在,我向我的网站添加了启用Silverlight的WCF服务,我希望通过SSL进行通信。如果我浏览到http s :// www.mydomain.com/myservice.svc,它会向我显示WSDL描述性“您已创建服务”页面,如预期,显示使用

创建客户端
svcutil.exe https:// ... 
  

编辑:我意识到wsdl文件中为svcutil显示的url实际上是指向Web服务器的物理盒名称,而不是正确的域。所以我完成了 this blog posting 中显示的步骤,使用adsutil脚本更新IIS中网站的SecureBinding。现在wsdl文件显示正确的SSL地址,但我仍然得到相同的错误。

现在我去尝试将我的Silverlight应用程序挂钩,但它不起作用,在异步调用的结果中返回异常,声明“远程服务器返回错误:NotFound 。我读过的一些博客谈到了通过创建一个测试Windows应用程序将其缩小到Silverlight问题,并尝试从中引用它。好吧,我做到了,甚至在常规的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)

尽管我使用HTTPS方案明确地将服务引用添加到Windows应用程序,但它正确地获取了所有方法,并在编辑器中的Intellisense中显示它们。

请注意,这是一项不需要在用户身上显式登录的服务。我将在我的SOAP信封中发送自定义标头,以验证请求是否来自我们的应用程序,我只想让掠夺者嗅探线并挑出自定义标头。

现在到代码中,我必须有一些愚蠢的小设置错误,因为从我读过的所有内容来看,这应该是一个相当简单的练习。

首先,我的服务的代码隐藏类使用以下属性进行修饰:

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

服务器上我的web.config的ServiceModel部分如下所示:

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

我的Windows应用程序中app.config的ServiceModel部分如下所示:

<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 个答案:

答案 0 :(得分:26)

我最后也有同样的问题。你的帖子帮助我找出了问题所在。这是我的服务模型部分。我发现密钥是 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>

答案 1 :(得分:11)

我最近正在处理这个问题,并希望添加一个调整。如果您按照上述说明操作,则可以使该服务使用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>

(取自我的代码库,根据需要调整behaviorConfiguration和binding)

答案 2 :(得分:8)

我只花了几个小时才发现这个问题,原来我的问题是服务名称

<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 :(得分:3)

就我而言,没有这些答案有帮助。

相反,我需要add a duplicate <binding> section that has no name attribute set

以下是我服务的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>

我希望有一天这可能对某人有所帮助。

答案 4 :(得分:2)

我遇到了同样的问题,花了一天时间来解决这个问题。最后,下面的配置使我能够进行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>

答案 5 :(得分:1)

一切似乎都非常有效,根本没有明显的错误......

只有一个观察/问题:你的* .svc文件位于哪里?

在错误消息中,我看到:

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

您的* .svc文件是否真的位于您网站的顶级虚拟目录中?

通常,* .svc文件位于IIS上的虚拟目录中,因此地址类似于:

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

当然,您可以将ASP.NET应用程序和WCF服务* .svc文件部署到IIS的根目录 - 但根据我的经验,它并不常见。

要检查一下......

马克

答案 6 :(得分:1)

好吧,我显然已经解决了这个问题,我完全不知道为什么/如何。

这就是我的所作所为。

  • 我添加了一个全新的EMPTY启用Silverlight的WCF服务
  • 然后我更新了web.config以反映这两项服务
  • 然后,我只是将第一项服务的所有内容复制并粘贴到第二项服务中,但名称除外。

为什么要修复它,我绝对不知道。

任何人的FWIW,这是我的新web.config ServiceModel部分,其中包含第二个服务......

<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 :(得分:1)

有几个答案让我重新配置我的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>

答案 8 :(得分:0)

之前它没有用,因为您将basicHttpBinding配置命名为“basicHttpBinding”,但未使用bindingConfiguration =“basicHttpBinding”

在您的标记中引用该配置

在通过添加其他服务配置工作的更改中,您确实引用了包含该节点的绑定配置,从而使其工作。

答案 9 :(得分:0)

另一件事是检查你是否遇到与OP相同的404错误。我摆弄了很多东西,但最后解决方案只是将命名空间添加到我的服务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>