2013-03-04 70 views
21

私はsslで使用したいASP.NET Web APIを持っています。現在、サーバーは自己署名証明書を使用しています。この時点では、httpとhttpsの両方が許可されています。私はhttpでうまく動作する非常に基本的なテストクライアントを持っていますが、httpsでは動作しません。私はhttpsで動作するように、以下のクライアントコードを変更する方法を知りたいです。現在IE、Firefox、Chromeはhttpとhttpsの両方を使用してWeb APIに接続できるため、クライアントコードだけでサーバー上のものを変更する必要はありません。クライアントコードは次のとおりです。ssl Web APIに接続する.NETクライアント

static void Main(string[] args) 
{ 
    try 
    { 
     if (args.Length != 1) 
     { 
      Console.WriteLine("Please provide a url, and only a url."); 
      return; 
     } 

     var url = new Uri(args[0]); 
     var urlAuthority = url.GetLeftPart(UriPartial.Authority); 
     var urlPathQuery = args[0].Substring(urlAuthority.Length); 
     HttpClient client = new HttpClient(); 
     client.BaseAddress = new Uri(urlAuthority); 
     HttpResponseMessage response = client.GetAsync(urlPathQuery).Result; 
     if (response.IsSuccessStatusCode) 
      Console.WriteLine(response.Content.ReadAsAsync<string>().Result); // expecting scalar results only 
     else 
      Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); 
    } 
    catch (Exception ex) 
    { 
     Exception tempEx = ex; 
     while (tempEx != null) 
     { 
      Console.WriteLine(tempEx.Message); 
      tempEx = tempEx.InnerException; 
     } 
    } 
} 

私のhttp URLで上記のコードを実行すると、うまくいきます。私はhttpsにURLを変更すると、次のエラーが出力されます。私が持っている

One or more errors occurred. 
An error occurred while sending the request. 
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. 
The remote certificate is invalid according to the validation procedure. 

一つの疑問は、それが暗号化された応答を返送する方法を知っているように、クライアントは、手動でサーバーに公開鍵を送信しなければならない場合である場合、またはこれは自動的に舞台裏で行われますか?そして2番目に、最後のエラーを見た後、私はクライアント内でcertの警告を無視して、この証明書が進んでいいということを信じるために何か他のことをしなければならないのだろうか?

+0

コンフィグレーションでトランスポートに設定されているセキュリティモードはありますか? – Joe

+0

別の例がここにあります:http://stackoverflow.com/a/42449178/112397 – TombMedia

答えて

38

C# Ignore certificate errors SOの質問をご覧ください。 ServicePointManagerを使用して証明書の検証を回避するために証明書検証ハンドラを追加できると思います。しかし、実稼働環境内で署名付き証明書を使用することはおそらく良い考えです。

ServicePointManager 
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true; 
+1

私はprodで署名付き証明書を使用することに同意しますが、この場合、私たちのprod Web APIは公開されません。なぜなら、私たちの管理下にある自動化されたクライアントからのみ接続されているからです。まずSSLが必要です。 – TTT

+0

私は2ポイント、1を持っています。このソリューションは、Dev環境とProd環境のコードの違いが必要です。私はProdが証明書エラーを無視するこのコードを必要としないことを意味します。 2.これはアプリケーション/言語固有の修正です。 jQueryのAJAXリクエストでこのAPIにアクセスする必要がある場合私の意見では、@Devinが述べたように、自己署名付き証明書は、ルート証明書に昇格することで開発マシン上で信頼できるものにする必要があります。このリンクを参照して、IIS ExpressおよびSSLを使用して開発環境をセットアップしてください。http://www.hanselman.com/blog/WorkingWithSSLAtDevelopmentTimeIsEasierWithIISExpress.aspx –

3

このエラーメッセージは、クライアントがSSLハンドシェイク中にサーバー証明書を信頼しないことを意味します。ブラウザによってはもう少し寛容で「赤いバー」を付けることもできますが、コードから呼び出すと401と拒否された呼び出しになります。

(クライアント証明書を使用していないと仮定しているため)IISでクライアント証明書の設定を行う必要はありません。

この例外メッセージは、クライアントで検証するときに自己署名証明書チェーンが拒否されたことを示しています。これを回避するには、(秘密鍵を使用せずに)自己署名証明書をエクスポートし、それをルート証明書としてクライアントマシンにインストールします。

これが機能しない場合は、新しいCA(認証局証明書)を作成し、CAと署名した新しいサーバー証明書を生成する必要があります。このCAは、最終的にルート証明書としてクライアントマシンにインストールする必要があります。

This is a good post makecertとpvk2pfxを使用するプロセスを示しています。

EDIT: It looks like there might be a way SSLエラーを無視するようHttpClientを設定します。しかし、最初からSSLエラーが発生しないようにすることを強くお勧めします。

+0

それを許可するようにクライアントコードで行うことはできません。証明書がクライアントマシンにルート証明書としてインストールされていないと、どのブラウザがこれをどのように達成しますか? – TTT

+0

@TTTすべてのクライアントには特定のルート証明書がインストールされています。 Verisignのルート証明書など。証明書がVerisignルート証明書によって署名されている(またはチェーン内にある)場合、ブラウザクライアントは証明書を信頼します。これはSSLの仕組みの中核です。 –

+0

私はそれを理解しています。しかし、私が試した3つのブラウザはすべて、SSLを使って同じURLに接続できますが、クライアントはできません。私はブラウザが何をしているのかをしたい。署名されていない証明書が自分のマシン上で信頼されていない場合、その証明書はブラウザ用に信頼されていませんが、ブラウザは引き続き使用できます。 – TTT

18

これは私に役立ちました。 GetAsyncの呼び出しの前に次の行を追加してください。

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

これはSSLエラーを無視します。これは、サーバーのIDを偽造できないイントラネット環境または閉鎖されたネットワークでのみ推奨されます。

関連する問題