5

为了忽略 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 块中的代码,这是将其重置为默认值的正确方法吗?
4

1 回答 1

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);
        }
    }
    
于 2015-10-08T02:52:23.390 回答