基于 SSL 的 WCF - 404 错误 [英] WCF over SSL - 404 error

查看:18
本文介绍了基于 SSL 的 WCF - 404 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我一定在这里遗漏了一些非常简单的东西,因为我已经用谷歌搜索了好几天,并在那里查看了数十个答案,然后在这里,无论我做什么,我都无法让它发挥作用"我试过了.当通过普通 HTTP 调用时,该服务工作得非常好.

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

现在,我向我的站点添加了一个启用 Silverlight 的 WCF 服务,我想通过 SSL 与之通信.如果我浏览到 https://www.mydomain.com/myservice.svc,它会按预期向我显示 WSDL 描述的您已创建服务"页面,这表明使用

创建您的客户端

svcutil.exe https://...

<块引用>

我意识到 wsdl 文件中为 svcutil 显示的 url 实际上指向 Web 服务器的物理框名称,而不是正确的域.所以我经历了 这篇博文 使用 adsutil 脚本更新 IIS 中网站的 SecureBinding.现在 wsdl 文件显示了正确的 SSL 地址,但我仍然遇到相同的错误.

现在我去尝试将我的 Silverlight 应用程序连接到它,但它不起作用,在异步调用的结果中返回异常,指出远程服务器返回错误:NotFound. 我读过的许多博客都谈到通过创建测试 Windows 应用程序并尝试从中引用它来将其缩小到 Silverlight 问题.好吧,我这样做了,甚至在尝试访问的常规 Windows 应用程序中SSL 上的服务我收到一个异常说明:

System.ServiceModel.EndpointNotFoundException:在 https://www.mydomain.com/mysubdir/myservice.svc 上没有侦听端点可以接受消息.这通常是由不正确的地址或 SOAP 操作引起的.有关更多详细信息,请参阅 InnerException(如果存在).--->System.Net.WebException:远程服务器返回错误:(404) 未找到.在 System.Net.HttpWebRequest.GetResponse()在 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

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

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

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

首先,我的服务的代码隐藏类装饰有以下属性:

<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>

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

<绑定><基本HttpBinding><绑定名称="basicHttpBinding"><安全模式="传输"><传输 clientCredentialType ="无"/></安全></binding></basicHttpBinding></绑定><行为><服务行为><行为名称=排名行为"><serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/><serviceDebug includeExceptionDetailInFaults="false"/></行为></serviceBehaviors></行为><serviceHostingEnvironment aspNetCompatibilityEnabled="true"><baseAddressPrefixFilters><add prefix="http://www.mydomain.com:80"/></baseAddressPrefixFilters></serviceHostingEnvironment><服务><service behaviorConfiguration="standingsBehavior" name="lijslwebdata"><endpoint address="" binding="basicHttpBinding" contract="lijslwebdata"/><!--<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>--></服务></服务></system.serviceModel>

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

<绑定><基本HttpBinding><绑定名称="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="缓冲"useDefaultWebProxy="true"><readerQuotas maxDepth="32" maxStringContentLength="8192"maxArrayLength="16384"maxBytesPerRead="4096" maxNameTableCharCount="16384"/><安全模式="传输"><transport clientCredentialType="None" proxyCredentialType="None" realm=""/><message clientCredentialType="UserName" algorithmSuite="默认"/></安全></binding></basicHttpBinding></绑定><客户><端点地址="https://www.mydomain.com/mysubdir/myservice.svc"绑定=基本HttpBinding"bindingConfiguration="BasicHttpBinding_lijslwebdata"contract="xdata.lijslwebdata" name="BasicHttpBinding_lijslwebdata"/></客户端></system.serviceModel>

解决方案

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

这就是我所做的.

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

为什么要修复它,我完全不知道.

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

<绑定><基本HttpBinding><绑定名称="basicHttpBinding"></binding><绑定名称="basicHttpsBinding"><安全模式="传输"><传输 clientCredentialType ="无"/></安全></binding></basicHttpBinding></绑定><行为><服务行为><行为名称=排名行为"><serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/><serviceDebug includeExceptionDetailInFaults="false"/></行为></serviceBehaviors></行为><serviceHostingEnvironment aspNetCompatibilityEnabled="true"><baseAddressPrefixFilters><add prefix="http://www.mydomain.com/"/></baseAddressPrefixFilters></serviceHostingEnvironment><服务><service behaviorConfiguration="standingsBehavior" name="lijslwebdata"><endpoint address="" binding="basicHttpBinding" contract="lijslwebdata"/><endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/></服务><service behaviorConfiguration="standingsBehavior" name="sslwebdata"><端点地址="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="sslwebdata"/><endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/></服务></服务></system.serviceModel>

Okay, I must be missing something utterly simple here, because I've been googling for days, and looking at dozens of answers there, and here on SO, and i just CANNOT get this to work, no matter what i've tried. The service works perfectly fine when called over plain HTTP.

Here's our setup... we have a domain, http://www.mydomain.com . We have an SSL certificate installed on that domain from thawte, just as we would if we were securing an e-commerce site. That all works fine, and i can go to https://www.mydomain.com and it works right. I'm running VS2008, .NET 3.5 site on Windows Server 2003 R2.

Now, I added a Silverlight-enabled WCF service to my site, which i want to communicate with over SSL. If i browse to https://www.mydomain.com/myservice.svc, it shows me the WSDL-descriptive "You have created a service" page as expected, which shows to create your client using

svcutil.exe https:// ... 

EDIT: I realized the url shown for the svcutil in the wsdl file was actually pointing to the physical box name of the web server, not the proper domain. So i went through the steps shown in this blog posting to update the SecureBinding of the website in IIS using the adsutil script. Now the wsdl file shows the correct SSL address, but i still get the same error.

Now i went and tried to hook my Silverlight app up to it, and it does not work, returning an exception in the result from the async calls, stating "The remote server returned an error: NotFound. A number of the blogs i've read talked about narrowing it down to Silverlight issues by creating a test Windows application, and trying to reference it from that. Well, I did that and even in a regular windows application trying to access the service over SSL i get an exception stating:

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)

This despite the fact that i explicitly added the service reference to the Windows app using the HTTPS scheme and it properly gets all the methods and shows them in Intellisense in the editor.

Note that this is a service which does NOT require explicit log in on the user's part. I am going to be sending custom headers in my SOAP envelopes to verify that the requests are coming from our app, and I just want to keep predators from sniffing the line and picking out the custom headers.

Now to the code, where i must just have some stupid little setting wrong, because from all i've read, this should be a fairly straightforward exercise.

First, my service's code-behind class is decorated with the following attributes:

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

The ServiceModel section of my web.config on the server looks like so:

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

And the ServiceModel section of the app.config in my Windows application looks like the following:

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

解决方案

Okay, I apparently fixed the issue, and I have absolutely no idea why/how.

Here's what I did.

  • I added a BRAND NEW EMPTY Silverlight-enabled WCF service
  • I then updated the web.config to reflect both services
  • I then literally just copied and pasted everything about the first service into the second service, except the name.

Why this fixed it, I have absolutely NO idea.

FWIW for anyone, here is my new web.config ServiceModel section with the second service in it...

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

这篇关于基于 SSL 的 WCF - 404 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆