多个线程设置ServicePointManager.ServerCertificateValidationCallback是否安全?

时间:2013-03-22 19:57:53

标签: c#

要忽略ssl证书错误,我在制作ServicePointManager.ServerCertificateValidationCallback之前在静态方法中设置HttpWebRequest。我只希望对内部请求执行此操作,因此我将属性重置为finally块中的默认值。但是因为它是一个Web应用程序,当多个线程修改属性时会出现问题吗?

以下是我使用该属性的方法

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 个答案:

答案 0 :(得分: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);
        }
    }