Silverlight 4 OOB +浏览器 HTTP 堆栈客户端证书 = 失败?
我遇到一个问题,当我使用 SSL 和客户端证书从浏览器外 Silverlight 4 应用程序调用 IIS 7.5(在 Windows 7 64 位上)时,它会失败,并显示消息“I/O 操作已由于线程退出或应用程序请求而中止(0x800703e3)”。该请求确实发送到 IIS。以下是失败请求跟踪的示例:
由于线程退出,I/O 操作已中止或申请请求。 (0x800703e3) http://www.slipjig.org/IISError.gif
我正在使用浏览器 HTTP 堆栈,因为客户端 HTTP 堆栈不支持客户端证书。尝试访问服务器的客户端代码是 Prism 模块加载器。如果我在浏览器外运行应用程序但忽略客户端证书,或者如果我在浏览器内运行应用程序但需要客户端证书,则它可以正常工作。似乎是两者的结合导致了问题。
我尝试了以下方法来收集更多信息:
- 使用 Fiddler 查看失败的请求。如果 Fiddler 正在运行,它就可以工作(大概是因为 Fiddler 以不同的方式处理客户端证书?);
- 创建了一个 .aspx Web 表单来提供模块 .xaps;
- 创建一个 HTTPModule 以查看是否可以在请求失败之前拦截该请求;
- 使用数据包嗅探器来查看是否可以判断客户端证书是否已正确发送。
尽管 Fiddler 的事情很有趣,但除了我在跟踪文件中看到的信息之外,上述内容都没有给我提供太多有用的信息。
有什么想法吗?提前致谢! 麦克风
I'm having an issue where IIS 7.5 (on Windows 7 64-bit) is failing when I call it from an out-of-browser Silverlight 4 app using SSL and a client certificate, with the message "The I/O operation has been aborted because of either a thread exit or an application request. (0x800703e3)". The request does make it to IIS. here is a sample from the failed request trace:
I am using the browser HTTP stack, because the client HTTP stack does not support client certificates. The client code attempting to hit the server is the Prism module loader. If I run the app out-of-browser but ignore client certs, or if I run the application in-browser but require client certs, it works fine. It seems to be the combination of the two that is causing the problem.
I tried the following to gather more info:
- Used Fiddler to view the failing request. It works if Fiddler is running (presumably because Fiddler is handling the client certificate differently?);
- Created an .aspx web form to serve up the module .xaps;
- Created an HTTPModule to see if I could intercept the request before it failed;
- Used a packet sniffer to see if I could tell if the client certificate was being sent correctly.
None of the above gave me much useful information beyond what I could see in the trace file, although the Fiddler thing is interesting.
Any ideas? Thanks in advance!
Mike
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为了这个问题,我连续几个星期都在苦苦思索。这是我学到的东西以及我最终如何解决这个问题的。
Prism的FileDownloader类使用System.Net.WebClient来加载模块。在 OOB 模式下,WebClient 似乎使用与 IE 相同的堆栈,但它显然要么不发送客户端证书,要么(更有可能)不与服务器正确协商 SSL/客户端证书握手。我这样说是因为:
我无法很好地了解网络上实际发生的情况;如果我使用 Fiddler,它会起作用,因为 Fiddler 会拦截与服务器的通信并自行处理客户端证书握手。由于 SSL,尝试使用数据包嗅探器显然不会告诉我任何信息。
所以 - 我首先在服务器端花了很多时间试图消除可能导致问题的东西(不需要的处理程序、模块、功能等)。
当这不起作用时,我尝试修改 Prism 源代码以使用浏览器的 HTTP 堆栈而不是 WebClient。为此,我创建了一个设计与 FileDownloader 类似的新类,实现 IFileDownloader,它使用浏览器堆栈。然后,我对 XapModuleTypeLoader(实例化下载器)进行了一些更改,以使其使用新类。这种方法失败了,并出现了我最初遇到的相同错误。
然后我开始研究是否可以使用商业第三方 HTTP 堆栈。我找到了一个支持我需要的功能并且支持 Silverlight 4 运行时的软件。我创建了另一个使用该堆栈的 IFileDownloader 实现,并且 BOOM - 它起作用了。
这种方法的好消息是,我不仅可以用它来加载模块,还可以用它来保护客户端和 REST API 之间的通信(我们之前打算放弃的好处)。
我计划向 Prism 提交一个补丁,以允许下载器在外部注册或绑定,因为它目前已硬编码为使用自己的 FileDownloader。如果有人对此或我正在使用的商业 HTTP 堆栈感兴趣,请联系我 (msimpson -at- abelsolutions -dot- com) 以获取链接和代码示例。
我必须这么说 - 我仍然不确定根本问题是在客户端还是服务器端的 HTTP 堆栈中,但对于 Microsoft 来说这仍然是一个失败。
I beat my head against the wall for weeks on this problem. Here's what I learned and how I finally worked around it.
Prism's FileDownloader class uses System.Net.WebClient to load modules. In OOB mode, WebClient seems to use the same stack as IE, but it apparently either doesn't send the client certificate, or (more likely) doesn't correctly negotiate the SSL/client cert handshake with the server. I say this because:
I couldn't get good visibility into what was actually happening over the wire; if I used Fiddler, it would work, because Fiddler intercepts communications with the server and handles the client certificate handshake itself. And trying to use a packet sniffer obviously wouldn't tell me anything because of SSL.
So - I first spent a lot of time on the server side trying to eliminate things (unneeded handlers, modules, features, etc.) that might be causing the problem.
When that didn't work, I tried modifying the Prism source code to use the browser's HTTP stack instead of WebClient. To do this, I created a new class similar in design to FileDownloader, implementing IFileDownloader, that used the browser stack. I then made some changes to XapModuleTypeLoader (which instantiates the downloader) to make it use the new class. This approach failed with the same error I was originally experiencing.
Then I started researching whether a commercial third-party HTTP stack might be available. I found one that supported the features I needed and that supported the Silverlight 4 runtime. I created another implementation of IFileDownloader that used that stack, and BOOM - it worked.
The good news with this approach is that not only can I use this to load modules, I can also use it to protect communications between the client and our REST API (a benefit we were going to give up, before).
I plan to submit a patch to Prism to allow the downloader to be registered or bound externally, as it's currently hard-coded to use its own FileDownloader. If anyone is interested in that or in the commercial HTTP stack I'm using, contact me (msimpson -at- abelsolutions -dot- com) for links and code samples.
And I must say this - I still don't know for sure whether the root problem is in the HTTP stack on the client side or the server side, but it's a FAIL on Microsoft's part nonetheless.
我们(Slipjig 和我)本周发现,似乎确实有办法解决这些问题,或者至少,我们正在努力确定是否存在可靠、可重复的方法。我们对此仍然不确定,但到目前为止我们知道的是:
首先,如果您有这样的代码,您可以开始使用浏览器或客户端堆栈发出请求:
首先,在您的应用程序中放置一个“WebBrowser”控件Silverlight XAML,并使其向您的 HTTPS 站点发送请求。
这可能会为用户弹出证书对话框。有什么大不了的。接受它。如果您只有一个证书,那么您可以关闭 IE 中的一个选项来抑制该消息。
然后,在用户调用的单独处理程序中,创建堆栈的实例(客户端或浏览器):
最后,回调:
What we (Slipjig and I) found out this week is that there does appear to be a way around these issues, or at least, we're on the trail to determining whether there is a reliable, repeatable way. We're still not positive on that, but here's what we know so far:
At first pass, if you have code like this you can start making requests with either the Browser or Client stack:
First, place a "WebBrowser" control in your Silverlight XAML, and make it send a request to your HTTPS site.
This may pop up the certificate dialog box for the user. Big deal. Accept it. If you have only one cert, then you can turn an option in IE off to suppress that message.
Then, in a separate handler invoke by the user, create an instance of your stack, either Client or Browser:
Finally, the Callback:
我遇到了同样的问题,我通过使用 makecert 创建证书来修复它。按照本文中的步骤 http://www.codeproject .com/Articles/24027/SSL-with-Self-hosted-WCF-Service 并将 CN 替换为您的 IP/域。就我而言,我已在本地计算机上测试了该服务并运行命令如下:
1) makecert -sv SignRoot.pvk -cy Authority -r signroot.cer -a sha1 -n "CN=Dev Certification Authority" -ss my -sr localmachine
运行第一个命令后,将证书从“个人”目录拖到“受信任的根证书颁发机构”
2) makecert -iv SignRoot.pvk -ic signroot.cer -cy end -pe -n
CN="localhost" -eku 1.3.6.1.5.5.7.3.1 -ss 我的-sr
本地机器-sky交换-sp
"Microsoft RSA SChannel Cryptographic Provider" -sy 12
如果您想要在另一台计算机上运行 silverlight 应用程序,请导出在步骤 1 中创建的证书,然后将其导入到您希望运行应用程序的任何计算机上。
I had the same issue and I fixed it by creating the certificate using makecert. Follow the steps from this article http://www.codeproject.com/Articles/24027/SSL-with-Self-hosted-WCF-Service and replace CN with your ip/domain. In my case I have tested the service on the local machine and run the commands as follows:
1) makecert -sv SignRoot.pvk -cy authority -r signroot.cer -a sha1 -n "CN=Dev Certification Authority" -ss my -sr localmachine
after running the first command drag the certificate from "Personal" directory to "Trusted Root Certification Authority"
2) makecert -iv SignRoot.pvk -ic signroot.cer -cy end -pe -n
CN="localhost" -eku 1.3.6.1.5.5.7.3.1 -ss my -sr
localmachine -sky exchange -sp
"Microsoft RSA SChannel Cryptographic Provider" -sy 12
In case you want to run the silverlight application on another machine, export the certificate created at step1 and then import it on any machine where you want your application to run.