4

SSL とクライアント証明書を使用してブラウザ外の Silverlight 4 アプリから IIS 7.5 (Windows 7 64 ビット) を呼び出すと、IIS 7.5 が失敗し、"The I/O operation hasスレッドの終了またはアプリケーションの要求により中止されました。(0x800703e3)". 要求は IIS に送信されます。失敗したリクエスト トレースのサンプルを次に示します。

スレッドの終了またはアプリケーションの要求により、I/O 操作が中止されました。(0x800703e3) http://www.slipjig.org/IISError.gif

クライアント HTTP スタックはクライアント証明書をサポートしていないため、ブラウザの HTTP スタックを使用しています。サーバーにアクセスしようとしているクライアント コードは、Prism モジュール ローダーです。アプリをブラウザー外で実行してもクライアント証明書を無視する場合、またはアプリケーションをブラウザー内で実行してもクライアント証明書が必要な場合でも、正常に動作します。この 2 つの組み合わせが問題を引き起こしているようです。

より多くの情報を収集するために、次のことを試しました。

  • Fiddler を使用して、失敗した要求を表示しました。Fiddler が実行されている場合は機能します (おそらく、Fiddler がクライアント証明書を別の方法で処理しているためでしょうか?)。
  • モジュール .xaps を提供する .aspx Web フォームを作成しました。
  • HTTPModule を作成して、リクエストが失敗する前に傍受できるかどうかを確認しました。
  • パケット スニファーを使用して、クライアント証明書が正しく送信されているかどうかを確認しました。

Fiddler の機能は興味深いものですが、上記のいずれからも、トレース ファイルで確認できる以上の有益な情報は得られませんでした。

何か案は?前もって感謝します!マイク

4

3 に答える 3

4

私はこの問題で何週間も壁に頭をぶつけました。これが私が学んだことと、最終的にどのようにそれを回避したかです。

Prism の FileDownloader クラスは、System.Net.WebClient を使用してモジュールをロードします。OOB モードでは、WebClient は IE と同じスタックを使用しているように見えますが、明らかにクライアント証明書を送信していないか、(より可能性が高い) SSL/クライアント証明書ハンドシェイクをサーバーと正しくネゴシエートしていません。私がこれを言うのは:

  • Firefox と Chrome を使用して .xap ファイルを正常に要求できました。
  • IE を使用して .xap ファイルを正常に要求できませんでした。
  • IIS は 403 ではなく 500 で失敗します。

ネットワーク上で実際に何が起こっているのかをよく把握できませんでした。Fiddler を使用した場合、Fiddler はサーバーとの通信を傍受し、クライアント証明書のハンドシェイク自体を処理するため、機能します。また、パケット スニファを使用しようとしても、明らかに SSL のために何もわかりません。

そのため、最初にサーバー側で多くの時間を費やして、問題の原因となっている可能性のあるもの (不要なハンドラー、モジュール、機能など) を排除しようとしました。

それがうまくいかなかったとき、WebClient の代わりにブラウザの HTTP スタックを使用するように Prism のソース コードを変更してみました。これを行うために、ブラウザー スタックを使用する IFileDownloader を実装する、設計が FileDownloader に似た新しいクラスを作成しました。次に、XapModuleTypeLoader (ダウンローダーをインスタンス化する) にいくつかの変更を加えて、新しいクラスを使用できるようにしました。このアプローチは、私が最初に経験したのと同じエラーで失敗しました。

次に、商用のサードパーティ HTTP スタックが利用可能かどうかの調査を開始しました。必要な機能をサポートし、Silverlight 4 ランタイムをサポートするものを見つけました。そのスタックと BOOM を使用する IFileDownloader の別の実装を作成しました - それは機能しました。

このアプローチの良いニュースは、これを使用してモジュールをロードできるだけでなく、クライアントと REST API 間の通信を保護するためにも使用できることです (以前はあきらめようとしていた利点です)。

現在、独自の FileDownloader を使用するようにハードコードされているため、ダウンローダーを外部で登録またはバインドできるようにするパッチを Prism に送信する予定です。それまたは私が使用している商用 HTTP スタックに興味がある人は、私 (msimpson -at- abelsolutions -dot-com) に連絡して、リンクとコード サンプルを入手してください。

そして、私はこれを言わなければなりません-根本的な問題がクライアント側のHTTPスタックにあるのかサーバー側にあるのかはまだわかりませんが、それでもMicrosoftの側ではFAILです.

于 2010-08-14T16:31:20.240 に答える
0

私たち (Slipjig と私) が今週発見したことは、これらの問題を回避する方法があるように見える、または少なくとも、信頼性が高く再現可能な方法があるかどうかを判断する道を進んでいるということです. 私たちはまだそれについて肯定的ではありませんが、これまでのところわかっていることは次のとおりです。

最初のパスで、このようなコードがあれば、ブラウザまたはクライアント スタックのいずれかでリクエストを開始できます。

まず、Silverlight XAML に "WebBrowser" コントロールを配置し、HTTPS サイトに要求を送信します。

これにより、ユーザーの証明書ダイアログ ボックスがポップアップ表示される場合があります。大したこと。受け入れ。証明書が 1 つしかない場合は、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;
            });
}
于 2010-12-08T00:45:38.987 に答える
0

同じ問題があり、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 exchange -sp "Microsoft RSA SChannel 暗号化プロバイダー" -sy 12

Silverlight アプリケーションを別のマシンで実行する場合は、ステップ 1 で作成した証明書をエクスポートしてから、アプリケーションを実行する任意のマシンにインポートします。

于 2012-08-13T11:29:18.200 に答える