【问题标题】:Silverlight 4 OOB + Browser HTTP Stack + Client Certificates = FAIL?Silverlight 4 OOB + 浏览器 HTTP 堆栈 + 客户端证书 = 失败?
【发布时间】:2011-03-13 03:42:13
【问题描述】:

当我使用 SSL 和客户端证书从浏览器外的 Silverlight 4 应用程序调用 IIS 7.5(在 Windows 7 64 位上)失败时,我遇到了一个问题,并显示消息“I/由于线程退出或应用程序请求,O 操作已中止。(0x800703e3)"。该请求确实到达了 IIS。这是来自失败请求跟踪的示例:

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

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

有什么想法吗?提前致谢! 迈克

【问题讨论】:

    标签: silverlight iis certificate out-of-browser


    【解决方案1】:

    我遇到了同样的问题,我通过使用 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 my -sr localmachine -sky 交换 -sp “Microsoft RSA SChannel 加密提供程序”-sy 12

    如果您想在另一台机器上运行 silverlight 应用程序,请导出在步骤 1 中创建的证书,然后将其导入您希望运行应用程序的任何机器上。

    【讨论】:

      【解决方案2】:

      我们(Slipjig 和我)本周发现,似乎确实存在解决这些问题的方法,或者至少,我们正在确定是否存在可靠、可重复的方法。我们对此仍不乐观,但目前我们知道的情况如下:

      首先,如果您有这样的代码,您可以开始使用浏览器或客户端堆栈发出请求:

      首先,在您的 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;
                  });
      }
      

      【讨论】:

        【解决方案3】:

        我在这个问题上苦苦挣扎了好几个星期。以下是我学到的知识以及我最终如何解决它。

        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 的失败。

        【讨论】:

        • 原来第三方堆栈要么有问题,要么我们无法弄清楚如何正确使用它,因为我们使用它会遇到各种错误。所以我在这个问题上回到了绘图板上:-(
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-07
        • 1970-01-01
        • 1970-01-01
        • 2011-01-01
        • 1970-01-01
        • 2011-11-21
        相关资源
        最近更新 更多