14

そこで、Oracle から公開された Web サービスを呼び出す C# コンソール アプリケーションに ServiceReference を追加しました。

すべてのセットアップが完了し、SSL (http) を使用していないときは桃のように動作します。現在、SSL を使用して設定しようとしていますが、サービス参照 (または Web 参照) に追加する際に問題が発生しています。たとえば、サービスが公開されている URL (https) を Visual Studio に追加しようとすると、適切な Web メソッドが返されません。

基になる接続が閉じられました: 送信時に予期しないエラーが発生しました。トランスポート ストリームから予期しない EOF または 0 バイトを受信しました。メタデータに解決できない参照が含まれています: ' https://srs204.mywebsite.ca:7776/SomeDirectory/MyWebService?WSDL '

私が抱えているもう 1 つの困惑は、証明書の管理と展開に関するものです。この小さなユーティリティを使用する必要がある約 1000 の外部クライアント サイトがあり、Web サービスに接続するには、適切な証明書ストアに証明書をインストールする必要があります。これを処理するための最良のアプローチについてはわかりません。それらはルートストアにある必要がありますか?

私はウェブでさまざまなオプションを調べてかなりの時間を費やしましたが、どこにもきれいな答えが得られません.

要約すると、ここでいくつかの質問があります。

1) SSL を使用する Visual Studio で Web サービスをセットアップするための良いリンクを持っている人はいますか?

2) 証明書の登録方法を教えてください。どの店舗に存在する必要がありますか?CertMgr のようなものを使用して登録できますか?

このようなものを設定するための一般的なグッドプラクティスを示す良い本/チュートリアル/何でもあるはずです。私はそれを見つけることができないようです!

4

5 に答える 5

31

さて、私はこれを理解しました。私が話したいよりもはるかに長い時間がかかりましたが、私の解決策を共有したかったのは、標準を見るのが私の大きな不満だからです. 「ああ、直りました!ありがとう!」実際に起こったことに誰もがぶら下がっている投稿。

そう。

根本的な問題は、デフォルトで Visual Studio 2008 が SSL ハンドシェイクに TLS を使用し、接続しようとしていた Oracle/Java ベースの Web サービスが SSL3 を使用していたことです。

Visual Studio 2008 で [サービス参照の追加...] を使用する場合、サービス ポイント マネージャーのセキュリティ プロトコルが SSL3 であることを指定する方法がありません。

そうでもなければ。

静的 WSDL ドキュメントを取得し、wsdl.exe を使用してプロキシ クラスを生成します。

wsdl /l:CS /protocol:SOAP /namespace:MyNamespace MyWebService.wsdl

次に、 C Sharp コンパイラを使用して、そのプロキシ クラスをライブラリ (.dll) に変換し、それを .Net プロジェクトの "参照" に追加できます。

csc /t:library /r:System.Web.Services.dll /r:System.Xml.dll MyWebService.cs

この時点で、「参照」にも System.Web.Services が含まれていることを確認する必要があります。

これで、コードに問題なく Web サービスを呼び出すことができるはずです。これを機能させるには、サービスをインスタンス化する前に、1 行の魔法のコードを追加する必要があります。

// We're using SSL here and not TLS. Without this line, nothing workie.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

さて、私の開発ボックスでのテストは素晴らしかったので、私は自分自身にかなり感銘を受けました. 次に、別のクライアント ボックスに展開しましたが、アクセス許可/権限の問題により、再度接続できませんでした。これは私にとって証明書のようなにおいがしました(においが何であれ)。これを解決するために、certmgr.exe を使用して、サイトの証明書をローカル マシンの信頼されたルートに登録しました。

certmgr -add -c "c:\someDir\yourCert.cer" -s -r localMachine root

これにより、証明書をクライアント サイトに配布し、ユーザーのために自動的にインストールすることができます。このような自動化された証明書登録に関して、さまざまなバージョンの Windows が「セキュリティにやさしい」かどうかはまだわかりませんが、これまでのところうまく機能しています。

この回答が一部の人々に役立つことを願っています。これに関するあなたのすべての助けといくつかの洞察を提供してくれたblowdartにも感謝します.

于 2009-05-22T13:20:03.307 に答える
4

Web サービスが自己署名証明書を使用しているようです。率直に言って、これは最善の方法ではありません。

あなたが大規模な組織であり、内部にあると仮定すると、独自の信頼できる認証局をセットアップできます。これはActive Directoryで特に簡単です。その CA から、Oracle サービスをホストするサーバーが証明書を要求できます。AD ポリシーを使用して、内部 CA のルート証明書をマシン ストアの信頼されたルートに配置することで信頼できます。これにより、Web サービスで証明書を手動で信頼または受け入れる必要がなくなります。

クライアント マシンが外部にある場合は、サービスを公開している人々に、Verisign、Thawte、GeoTrust などのよく知られた CA のいずれかから、またはインストール バンドルの一部として「本物の」証明書を購入してもらう必要があります。パブリック証明書を取得し、すべてのマシンのマシン レベルで信頼されたルート証明機関にインストールします。これには問題があります。たとえば、証明書を取り消す方法はありませんが、プロンプトは削除されます。

于 2009-05-20T13:26:09.207 に答える
1

マット、

私もそのような問題を抱えていましたが、certmgr.exe を使用してリモート マシンの信頼されたルートに証明書を追加することを回避する方法があります。

X509Store store;
store = new X509Store("ROOT", StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);

「証明書オブジェクト」は次のように作成できます。

X509Certificate2 certificate = new X509Certificate2("Give certificate location path here");
于 2009-07-29T18:26:07.300 に答える
1

コメントする評判がないので、SSL3 を強制するための Mat Nadrofsky の回答とコード サンプルも、次のようなエラーの解決策であることに言及したいと思います。

https://xxxx/whateverへの HTTP 要求の作成中にエラーが発生しました。これは、HTTPS の場合、サーバー証明書が HTTP.SYS で適切に構成されていないことが原因である可能性があります。これは、クライアントとサーバー間のセキュリティ バインディングの不一致が原因である可能性もあります。

使うだけ

// We're using SSL here and not TLS. Without this line, nothing workie.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

マットが述べたように。HTTPS の SAP NetWeaver PI サーバーでテスト済み。ありがとう!

于 2011-01-24T19:27:39.093 に答える
1

この素晴らしいヒントをありがとう、あなたのものをざっと見てみると、たくさんの良いアイデアが浮かんでいます. ここに少し追加します-webMethodsを理解しているところです.(驚き!)接続したOracleアプリサーバーと同じ問題があります(TLSではなくSSL3)。あなたのアプローチはうまくいきました。これが私の補遺です。

静的クラス「Factory」を指定して、次の 2 つの便利な項目を提供します。

/// <summary>
/// Used when dispatching code from the Factory (for example, SSL3 calls)
/// </summary>
/// <param name="flag">Make this guy have values for debugging support</param>
public delegate void CodeDispatcher(ref string flag);

/// <summary>
/// Run code in SSL3 -- this is not thread safe. All connections executed while this
/// context is active are set with this flag. Need to research how to avoid this...
/// </summary>
/// <param name="flag">Debugging context on exception</param>
/// <param name="dispatcher">Dispatching code</param>
public static void DispatchInSsl3(ref string flag, CodeDispatcher dispatcher)
{
  var resetServicePoint = false;
  var origSecurityProtocol = System.Net.ServicePointManager.SecurityProtocol;
  try
  {
    System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3;
    resetServicePoint = true;
    dispatcher(ref flag);
  }
  finally
  {
    if (resetServicePoint)
    {
      try { System.Net.ServicePointManager.SecurityProtocol = origSecurityProtocol; }
      catch { }
    }
  }
}

そして、このものを消費します (すでに推測しているように、とにかくここにドラムロールを入れてください):

    var readings = new ArchG2.Portal.wmArchG201_Svc_fireWmdReading.wmdReading[] {
      new ArchG2.Portal.wmArchG201_Svc_fireWmdReading.wmdReading() {
        attrID = 1, created = DateTime.Now.AddDays(-1), reading = 17.34, userID = 2
      },
      new ArchG2.Portal.wmArchG201_Svc_fireWmdReading.wmdReading() {
        attrID = 2, created = DateTime.Now.AddDays(-2), reading = 99.76, userID = 3
      },
      new ArchG2.Portal.wmArchG201_Svc_fireWmdReading.wmdReading() {
        attrID = 3, created = DateTime.Now.AddDays(-5), reading = 82.17, userID = 4
      }
    };
    ArchG2.Portal.Utils.wmArchG201.Factory.DispatchInSsl3(ref flag, (ref string flag_inner) =>
    {
      // creates the binding, endpoint, etc. programatically to avoid mucking with
      // SharePoint web.config.
      var wsFireWmdReading = ArchG2.Portal.Utils.wmArchG201.Factory.Get_fireWmdReading(ref flag_inner, LH, Context);
      wsFireWmdReading.fireWmdReading(readings);
    });

これでうまくいきます。もう少し時間があれば、スレッドの問題を解決します (または解決しません)。

于 2010-11-22T20:21:12.477 に答える