(我看到几个与我的问题有关的问题,但是没有一个解决方案对我有用,因为我在生产中遇到了这个问题,而不是在本地开发期间,我已经尝试了所有提议的修复。)
我有一个使用IIS托管的WCF服务的Silverlight 4应用程序。在生产中,这些服务通过HTTPS访问。尽管有a valid crossdomain.xml文件,我仍然在访问服务时得到着名的“安全错误”:
尝试向URI“https://MYDOMAIN/MYSERVICE.svc”发出请求时发生错误。这可能是由于尝试在没有适当的跨域策略的情况下以跨域方式访问服务,或者是不适合SOAP服务的策略。您可能需要联系服务的所有者以发布跨域策略文件,并确保它允许发送与SOAP相关的HTTP标头。在不使用InternalsVisibleToAttribute属性的情况下,在Web服务代理中使用内部类型也可能导致此错误。有关更多详细信息,请参阅内部异常。 ---> System.Security.SecurityException ---> System.Security.SecurityException:安全错误...
使用Fiddler我可以看到没有请求crossdomain.xml或clientaccesspolicy.xml。有一个CONNECT请求到服务器,但这就是全部。
我已经读过,当服务器发出无效证书时,也会引发此错误,虽然它表示有crossdomain.xml / clientaccesspolicy.xml的问题。在我的场景中似乎并非如此。
我确定以下设置正确: 1. crossdomain.xml有效并托管在站点的根目录中 2.服务确实有效(我们有其他客户使用各种技术,包括依赖于crossdomain.xml的Adobe Flex。) 3. Silverlight应用程序确实有效(在共享开发服务器上可以正常使用本地服务和服务***) 4. Silverlight应用程序甚至不尝试请求crossdomain.xml或clientaccesspolicy.xml(由Fiddler确认) 5. Silverlight应用程序使用适当的配置通过https访问WCF。以下是配置:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyServices" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://MYDOMAIN/MYSERVICE.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyServices" contract="Services.IMyServices" name="BasicHttpBinding_IMyServices" />
</client>
</system.serviceModel>
</configuration>
还有什么可以导致这种问题?可能是因为Web服务器是负载平衡的吗?或者我没有注意到证书有问题吗?如果你能够至少指出我正确的方向,将非常感激。
(***值得一提的是:我在开发环境中遇到了类似的问题。尽管有一个正确的crossdomain.xml而且没有使用HTTPS,Silverlight应用程序无法在共享开发服务器上访问WCF服务。我在周围工作它通过在IE中将开发服务器添加为可信站点。然而,这种相同的解决方法不适用于生产,即使这样也不是一个可接受的解决方法。但是我必须在开发环境中这样做的事实使我担心我一路上都错过了什么......)
问题是我缺少clientaccesspolicy.xml。在这种情况下,使用crossdomain.xml是不够的。我认为这是因为WCF调用不仅仅是跨浏览器而且是跨协议(Silverlight应用程序通过http提供,但服务是通过https提供的)。
另外,我的clientaccesspolicy.xml必须明确允许访问http,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="SOAPAction">
<!-- IMPORTANT! Include these lines -->
<domain uri="http://*"/>
<domain uri="https://*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
它现在就像一个魅力。
一路上让我绊倒的事情:
我有同样的错误,当我尝试通过http拨打我的网站时,我的服务已经通过https失败了。发生此错误是因为我的ISS没有证书,因此,当应用程序尝试下载clientaccesspolicy时,它失败了。
查看浏览器上的任何调试工具,查找clientaccesspolicy文件,然后检查是否正在下载。