单个WebClient实例的证书验证逻辑

时间:2018-01-02 09:12:28

标签: c# .net validation ssl

我正在使用继承自MyWebClient的{​​{1}}来发出http(s)请求。 我想跳过WebClient的某些实例的SSL证书验证。这就是为什么我引入了指示是否应该进行证书验证的属性。但是,当我尝试设置验证回调时:

MyWebClient

验证检查全局应用。我知道ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack; 可以设置HttpWebRequest,它将在实例级别设置。但是我没有找到为WebClient设置相同的方法。

任何想法,如果可能的话? .Net 4.5.1

1 个答案:

答案 0 :(得分:2)

您需要覆盖GetWebRequest,调用基本实现并将其转换为HttpWebRequest。从那里,您可以根据WebClient实例检查逻辑添加自定义。类似的东西:

class MyWC:WebClient
{

   public MyWC() {
       Validate = false;
   }

   public bool Validate {get;set;} // yes/no

   protected override WebRequest GetWebRequest(Uri url)
   {
        // this is called for each DownloadXXXX call
        var _req = (HttpWebRequest) base.GetWebRequest(url);

        // if Validate is true 
        if (Validate) {
            // set the callback on this request
            _req.ServerCertificateValidationCallback  = (s,cert,chain,polErr)=> {
                // do some check, only allow SE certificates here
                return cert.Subject.Contains(".stackexchange.com");
            };
        }
        return _req;
    }
}

上面的课将如下使用:

var mywc = new MyWC();

mywc.Validate = true;

mywc.DownloadString("https://stackoverflow.com");
mywc.DownloadString("https://superuser.com/questions");
mywc.DownloadString("https://google.com"); // this will throw
// The underlying connection was closed: 
// Could not establish trust relationship for the SSL/TLS secure channel

mywc.Validate = false;

mywc.DownloadString("https://google.com"); // this will  work


var normal = new WebClient();
normal.DownloadString("https://google.com"); // and the default webclient will work
// no global certificate validation