ServicePointManager.ServerCertificateValidationCallback 沖突的解決


    ServicePointManager是用於創建、 維護和刪除的實例的靜態類ServicePoint類。

    當應用程序請求對 Internet 資源統一資源標識符 (URI) 的連接通過ServicePointManager對象,ServicePointManager返回ServicePoint對象,其中包含的主機和方案通過 URI 標識的連接信息。 如果沒有現有ServicePoint方案,該主機以及對象ServicePointManager對象返回現有ServicePoint對象; 否則為ServicePointManager對象創建一個新ServicePoint對象。

    .NET Framework 4.6 包括一個新的安全功能,將阻止不安全的密碼和哈希算法的連接。 默認情況下,使用 TLS/SSL 通過例如 HttpClient、 HttpWebRequest、 FTPClient、 SmtpClient、 SslStream 等的 Api 和面向.NET Framework 4.6 的應用程序獲得更安全行為。

     開發人員可能想要選擇退出此行為以便保持其現有 SSL3 服務或 TLS 帶 RC4 服務與互操作性。 This article說明如何修改你的代碼,以便禁用新的行為。

     當我們要使用servicepointmanager.servercertificateValidationCallback驗證我們請求的證書時,如果請求是一個https請求,並且有多個線程並發請求的話,由於servicepointmanager是一個全局變量,只設置一次那么整個相關的https的請求都會進入這個回調函數中,並且不能單獨設置,這個時候你就要注意使用方法了,如果你想設置多個回調來分別區分的話,由於多線程的存在,會使得你的回調亂串,即回調不知道使用了那個,有興趣的朋友可以開多線程測試一下。

    基於以上的原因,其實在使用這個類時,最好的方法是:由於serverpointmanger是一個全局變量,那個全局最好就只設置一次回調方法,所有的請求都到這里去區分,這里怎么區分請求是有技巧的,

 1 public delegate bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) 

    回調方法如上,我們可以看這個函數的參數,總共三個,其中有兩個是無法更改,只有第一個參數,是一個object類型,那我們就利用這個參數,讓我們的請求從這個參數中把參數帶過來一個標志或其他參數,由於是https請求,所以一般我們使用的是HttpWebRequest這個類來請求路徑,我們可以在這個類中添加Headers或者cookies參數,並且是會傳到上面的回調的sender里的。

 1 HttpWebRequest request = null;
 2             HttpWebResponse response = null;
 3             StreamReader streamReader = null;
 4 
 5                 var encoding = Encoding.UTF8;
 6 
 7                 request = (HttpWebRequest)WebRequest.Create(url);
 8                 request.Method = "post";
 9                 request.ContentType = "text/xml";
10                 request.Headers.Add("charset:utf-8");
11                 request.Timeout = 15 * 1000; // 15 秒
12 
13                 request.Headers.Set(HttpRequestHeader.UserAgent, "login");

使用方案:

1 private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
2         {
3                     bool IsLogin = false;
4                     HttpWebRequest httpWebrequest = (HttpWebRequest)sender;
5                     string domain = httpWebrequest.Address.Host;
6   }

通過以上方案即可解決多線程調用證書驗證,並帶參數區分的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM