2013-03-22 97 views
5

要忽略ssl證書錯誤,我在製作HttpWebRequest之前以靜態方法設置ServicePointManager.ServerCertificateValidationCallback。我只希望完成內部請求,因此我將該屬性重置爲finally塊中的默認值。但是因爲它是一個Web應用程序,當多個線程修改屬性時會有問題嗎?多線程設置ServicePointManager.ServerCertificateValidationCallback安全嗎?

這裏是我如何使用屬性

public static String GetResource() 
{ 
    try 
    {   
     ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };   
    } 
    catch() 
    { 
    } 
    finally 
    { 
     ServicePointManager.ServerCertificateValidationCallback -= delegate { return false; }; 
    }  
} 
  1. 將這個代碼是線程安全的? msdn上的文檔說任何類型的ServicePointManager靜態成員都是線程安全的,但我只是想確認一下。 http://msdn.microsoft.com/en-us/library/zkfa48de%28v=vs.80%29.aspx
  2. finally塊中的代碼是將其重置爲默認值的正確方法嗎?
+1

不,這不會是 「線程安全的」。回調可以隨時通過任何其他線程進行更改。 – 2013-03-22 20:02:18

+1

順便說一句,就靜態成員而言,「線程安全」僅僅意味着這些成員自動修改靜態(如果有的話)。修改'ServerCertificateValidationCallback'的兩個線程在這方面是「線程安全的」。但是,從應用程序的角度來看,這不是線程安全的,因爲一個線程的數據(*它*'ServerCertificateValidationCallback'值)可能被另一個線程覆蓋 - 可能導致線程中的代碼出現故障。在無法控制的線程中,無法同步對「ServerCertificateValidationCallback」的訪問。 – 2013-03-22 20:12:11

+0

謝謝彼得的回覆。我在他們提出這種技術的地方看到了很多帖子,但顯然它不起作用。我不確定忽略內部Web請求的SSL證書錯誤的最佳方法是什麼。 – user1689030 2013-03-25 20:36:47

回答

5

如果你需要重寫默認證書驗證,請考慮以下的一種或多種:

  1. ServerCertificateValidationCallback一次且僅一次 - 應用在啓動期間或可能在靜態構造函數。這消除了線程爭用的風險。
  2. 既然你讓安全更加寬容,限制行爲調試版本與條件編譯:

    #if DEBUG 
        ServicePointManager.ServerCertificateValidationCallback += Callback; 
    #endif 
    
  3. 最後,請記住您的委託是一個豐富的功能。您不必簡單地返回true。您可以詢問請求並決定如何處理它。

    ServicePointManager.ServerCertificateValidationCallback += Callback; 
    
    static bool Callback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) 
    { 
        if (IsInternalRequest(sender)) 
        { 
         return true; 
        } 
        else 
        { 
         return IsExternalRequestValid(sender, certificate, chain, sslPolicyErrors); 
        } 
    }