Silverlight 4 OOB +浏览器HTTP堆栈+客户端证书= FAIL?

问题描述:

我遇到一个问题,当我使用SSL和客户端证书从浏览器外的Silverlight 4应用程序中调用IIS 7.5(在Windows 7 64位上)时失败,并显示消息“The I/O操作因线程退出或应用程序请求而中止(0x800703e3)“。该请求确实将其发送给IIS。这里是从失败请求跟踪的样本:Silverlight 4 OOB +浏览器HTTP堆栈+客户端证书= FAIL?

The I/O operation has been aborted because of either a thread exit or an application request. (0x800703e3) http://www.slipjig.org/IISError.gif

我使用的浏览器HTTP堆栈,因为客户端HTTP堆栈不​​支持客户端证书。试图访问服务器的客户端代码是Prism模块加载器。如果我在浏览器外运行应用程序,但忽略客户端证书,或者如果我在浏览器中运行应用程序,但需要客户端证书,则它可以正常工作。这似乎是导致问题的两者的结合。

我尝试了以下收集更多的信息:

  • 二手提琴手查看失败的请求。如果Fiddler正在运行,它可以工作(大概是因为Fiddler以不同的方式处理客户端证书?);
  • 创建一个.aspx web表单来提供模块.xaps;
  • 创建一个HTTPModule以查看在请求失败之前是否可以拦截请求;
  • 使用数据包嗅探器来查看我是否可以判断客户端证书是否正确发送。

除了我在跟踪文件中可以看到的信息,以上都没有给我提供太多有用的信息,尽管Fiddler的事情很有趣。

任何想法?提前致谢! 迈克

我在这个问题上击败了我的头靠墙。这就是我学到的东西,以及我最终如何解决这个问题。

Prism的FileDownloader类使用System.Net.WebClient加载模块。在OOB模式下,WebClient似乎使用与IE相同的堆栈,但它似乎不发送客户端证书,或者(更可能)未正确协商与服务器的SSL /客户端证书握手。我这样说是因为:

  • 我能够使用Firefox和Chrome成功请求.xap文件;
  • 我是不是能够使用IE成功请求.xap文件;
  • IIS会给出一个500,而不是403

我不能得到良好的可视性什么实际发生过的丝;如果我使用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的一部分。

+0

原来,第三方堆栈或者是越野车,或者我们无法弄清楚如何正确使用它,因为我们会使用它来获取各种错误。所以我回到了这个问题上的绘图板上:-( – slipjig 2010-12-02 20:47:41

我们(Slipjig和I)本周发现的是,似乎有解决这些问题的方法,或者至少我们正在确定是否存在可靠的可重复方法。我们仍然不能对积极的,但这里是我们目前为止知道:

在第一阶段,如果你有这样的代码,你可以开始用浏览器或客户端堆栈请求:

首先,在您的Silverlight XAML中放置一个“WebBrowser”控件,并使其向HTTPS站点发送请求。

这可能会弹出用户的证书对话框。大不了。接受。如果您只有一个证书,那么您可以在IE中关闭一个选项以禁止该消息。

private void Command_Click(object sender, RoutedEventArgs e) { 
    // This does not pop up the cert dialog if the option to take the first is turned on in IE settings: 
    BrowserInstance.Navigate(new Uri("https://www.SiteThatRequiresClientCertificates.com/")); 
} 

然后,在一个单独的处理程序被用户调用,创建堆栈的一个实例,客户端或浏览器:

private void CallServer_Click(object sender, RoutedEventArgs e) { 
      // Works with BrowserHttp factory also: 
      var req = WebRequestCreator.ClientHttp.Create(new Uri("https://www.SiteThatRequiresClientCertificates.com/")); 
      req.Method = "GET"; 
      req.BeginGetResponse(new AsyncCallback(Callback), req); 
} 

最后,回调:

private void Callback(IAsyncResult result) 
{ 
      var req = result.AsyncState as System.Net.WebRequest; 
      var resp = req.EndGetResponse(result); 
      var content = string.Empty; 
      using (var reader = new StreamReader(resp.GetResponseStream())) { 
       content = reader.ReadToEnd(); 
      } 
      System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => 
      { 
       Results.Text = content; 
      }); 
} 

在事实上,问题的解决方案可能如此简单: http://forums.silverlight.net/forums/p/196906/458328.aspx

唯一需要的是将证书放置到受信任的根存储中。但不幸的是,这并不适用于我的情况,我仍然在为这个问题而努力。

+1

该链接不再工作。 – emartel 2012-11-19 02:47:48

我有同样的问题,我通过使用makecert创建证书来解决它。按照本文http://www.codeproject.com/Articles/24027/SSL-with-Self-hosted-WCF-Service中的步骤操作,并用您的ip/domain替​​换CN。在我的情况下,我已经在本地机器上测试了该服务,并运行以下命令:

1)makecert -sv SignRoot.pvk -cy权限-r signroot。CER -a -n SHA1“CN =开发证书颁发机构” -SS我-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 my -sr localmachine -sky exchange -sp “Microsoft RSA SChannel加密提供程序“-sy 12

如果要在另一台机器上运行silverlight应用程序,请导出在步骤1创建的证书,然后将其导入到任何计算机上你想让你的应用程序运行。