2013-03-04 160 views
21

我有一個ASP.NET Web API,我希望使用ssl。目前服務器正在使用自簽名證書,並且此時都允許http和https。我有一個非常基本的測試客戶端,可以正常使用http,但不適用於https。我想知道如何修改下面的客戶端代碼,以便它可以使用https。目前,IE,Firefox和Chrome都可以使用http和https(帶有證書警告)連接到Web API,所以這使我相信我不應該修改服務器上的任何內容,只需在客戶端代碼中修改。這裏的客戶端代碼:.NET客戶端連接到ssl Web API

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,它工作正常。當我更改URL爲https以下錯誤打印:

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. 

我有一個問題是,如果客戶端必須手動發送公鑰給服務器,因此它知道如何發送回一個加密的響應,或者如果這在幕後自動發生?第二,現在在看到最後一個錯誤之後,我想知道如果我還需要在客戶端執行其他操作來忽略證書警告,並且相信這個證書可以繼續使用呢?

+0

您是否已將安全模式設置爲在您的配置中傳輸? – Joe 2013-03-04 16:10:04

+0

另一個例子可以在這裏找到:http://stackoverflow.com/a/42449178/112397 – TombMedia 2017-02-24 22:15:30

回答

38

看看C# Ignore certificate errors SO問題。我相信您可以使用ServicePointManager添加證書驗證處理程序來規避證書驗證。儘管在生產環境中使用簽名證書可能是一個好主意。

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

我同意在prod中使用簽名證書,但在這種情況下,我們的prod Web API將不會公開,因爲它只與我們控制下的自動化客戶端連接,但它仍然在互聯網上,這就是爲什麼我們首先需要SSL。 – TTT 2013-03-04 17:05:57

+0

我有2點要求。1.此解決方案需要Dev和Prod環境之間的代碼差異。我的意思是Prod不需要這個代碼,它忽略了證書錯誤。 2.這是應用程序/語言特定的修復程序。如果jquery AJAX請求需要訪問此API,該怎麼辦?在我看來,正如@Devin所說,通過推廣到Root證書,自簽名證書應該在開發機器上得到信任。使用IIS Express和SSL,請參閱此鏈接安裝開發環境,無需警告http://www.hanselman.com/blog/WorkingWithSSLAtDevelopmentTimeIsEasierWithIISExpress.aspx – 2016-06-16 20:06:21

3

此錯誤消息表示客戶端在SSL握手期間不信任服務器證書。有些瀏覽器更寬容一些,並給你一個「紅色欄」,但是從代碼調用將導致401和被拒絕的呼叫。

您不需要對IIS中的客戶端證書設置進行任何操作(因爲我假設您沒有使用客戶端證書)。

此異常消息告訴您,在客戶端進行驗證時,自簽名證書鏈會被拒絕。您可能要通過導出(無私鑰),自簽名證書並將其作爲root證書安裝在客戶機上來解決此問題。

如果這不起作用,您需要創建一個新的CA(證書頒發機構證書),然後生成一個新的CA服務器證書。這個CA最終必須作爲根證書安裝在客戶端機器上。

This is a good post顯示使用makecert和pvk2pfx的過程。

編輯: It looks like there might be a way配置HttpClient忽略SSL錯誤。但是,我強烈建議您儘量不要從一開始就出現SSL錯誤。

+0

那麼在客戶端代碼中沒有什麼可以告訴它允許它嗎?沒有證書作爲root證書安裝在客戶端機器上,所有瀏覽器如何完成此操作? – TTT 2013-03-04 16:22:58

+0

@TTT所有客戶端都安裝了某些根證書。例如Verisign根證書。如果證書通過Verisign根證書籤名(或在鏈中),則瀏覽器客戶端信任該證書。這是SSL如何工作的核心。 – 2013-03-04 16:24:21

+0

我明白這一點。但是我嘗試過的所有3個瀏覽器都可以使用SSL連接到相同的URL,但我的客戶端不能。我想要做瀏覽器正在做的事情。如果未簽名的證書在我的機器上不受信任,那麼它對於瀏覽器也不信任,但瀏覽器仍然可以繼續。 – TTT 2013-03-04 16:37:14

18

這對我有效。在對GetAsync的調用之前添加以下內容。

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

這會忽略SSL錯誤。這隻能在不能僞造服務器身份的Intranet環境或其他封閉網絡中推薦。