2010-07-08 2 views
4

У меня возникла проблема, когда IIS 7.5 (в Windows 7 64-разрядной версии) терпит неудачу, когда я вызываю его из приложения браузера Silverlight 4 вне браузера, используя SSL и сертификат клиента, с сообщением «I/O из-за выхода нити или запроса приложения (0x800703e3) ". Запрос отправляется в IIS. вот пример из отказавшего запроса следа:Silverlight 4 OOB + браузер HTTP Stack + Client Certificates = 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 работает (по-видимому, потому что Fiddler обрабатывает клиентский сертификат по-разному?);
  • Создал .aspx веб-форму для обслуживания модуля .xaps;
  • Создал HTTPModule, чтобы узнать, могу ли я перехватить запрос до его срыва;
  • Использовал сниффер пакетов, чтобы узнать, могу ли я сказать, правильно ли отправлен сертификат клиента.

Ничего из вышеперечисленного не предоставило мне много полезной информации, кроме того, что я мог видеть в файле трассировки, хотя вещь Fiddler интересна.

Любые идеи? Заранее спасибо! Mike

ответ

4

Я долго бил головой о стену по этой проблеме. Вот что я узнал и как я, наконец, работал над этим.

В классе FileDownloader Prism используется System.Net.WebClient для загрузки модулей. В режиме OOB WebClient, похоже, использует тот же стек, что и IE, но, по-видимому, он либо не отправляет сертификат клиента, либо, скорее всего, неправильно согласовывает квитирование сертификата SSL/клиента с сервером. Я говорю это потому, что:

  • Я смог успешно запросить файлы .xap с помощью Firefox и Chrome;
  • Я был не смог успешно запросить файлы .xap с использованием IE;
  • 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

0

На этой неделе мы обнаружили, что, по-видимому, существует проблема с этими проблемами или, по крайней мере, мы находимся на пути к определению того, существует ли надежный, повторяемый способ. Мы до сих пор не уверен в том, что, но вот то, что мы знаем до сих пор:

На первом проходе, если у вас есть код, как это вы можете начать делать запросы с любого браузера или клиента стека:

Во-первых, поместите элемент управления «WebBrowser» в свой Silverlight XAML и отправьте запрос на ваш сайт 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; 
      }); 
} 
0

В факт решения проблемы может быть таким же простым, как и здесь: http://forums.silverlight.net/forums/p/196906/458328.aspx

Единственное, что требуется, - это поместить сертификат в доверенное корневое хранилище. Но, к сожалению, это не сработало в моем случае, и я все еще борюсь с этой проблемой.

+1

Ссылка больше не работает. – emartel

0

У меня была такая же проблема, и я исправил ее, создав сертификат с помощью makecert. Выполните шаги из этой статьи http://www.codeproject.com/Articles/24027/SSL-with-Self-hosted-WCF-Service и замените CN своим ip/domain. В моем случае я проверил сервис на локальном компьютере и выполнил следующие команды:

1) makecert -sv SignRoot.pvk -cy authority -r signroot.CER -a sha1 -n "Орган по сертификации CN = Dev" -sS мой -sr LocalMachine

после выполнения первой команды перетащить сертификат из каталога "Personal" в "Доверенные корневые центры сертификации"

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

Если вы хотите запустить приложение silverlight на другой машине, экспортируйте сертификат, созданный на шаге 1, а затем импортируйте его на любую машину, вы хотите, чтобы ваше приложение запускалось.

Смежные вопросы