如何将“ServerCertificateValidationCallback”属性设置回其默认行为?

时间:2010-11-11 16:00:28

标签: .net vb.net ssl ssl-certificate

我在单个方法中使用以下代码行来显式检查并信任来自以下主机的SSL证书:MyTrustedCompany.com:

ServicePointManager.ServerCertificateValidationCallback = Function(obj As [Object], certificate As X509Certificate, chain As X509Chain, errors As SslPolicyErrors) (certificate.Subject.Contains("CN=MyTrustedCompany.com"))

代码没问题 - > 100%完美地运作。

问题是,它太遥远了。我认为它的范围只能在我对它进行十分转换的方法中,但显然它是'ServicePointManager'对象上的共享属性,然后必须保留整个应用程序,这是我不想要的。

问题是后来我打电话给我的网络服务,并得到“无法建立信任关系...”的例外。这是因为在上面的代码行中,我检查了该方法的SSL证书的主机名。我很快就从回调中测试了返回'True',因此所有证书都是可信任的,而不是检查一个特殊名称(即MyTrustedCompany)和子请求工作。这就是我知道这个回调赋值到达父亲的方法。当然,我可以扩展回调以包含所有其他证书名称,但我而不是做的是将'ServerCertificateValidationCallback'设置回其默认行为。就像下面的伪代码一样:

ServicePointManager.ServerCertificateValidationCallback = Nothing  'Default checking behavior

如何删除自定义验证并将其设置回默认行为?谢谢!

5 个答案:

答案 0 :(得分:13)

这实际上似乎有效(尽可能简单)并使对象以默认方式运行。

ServicePointManager.ServerCertificateValidationCallback = Nothing

答案 1 :(得分:4)

您只想对某些网址返回true, 但除此之外,这可以做你想要的,留下使用多个代表的可能性。每个回调的逻辑可以包括通过反射进行检查,以便回调仅在从某些组件调用时返回true,从而在某些URL和某些应用程序之间创建一种隧道。

使用此代码的一种方法: 1.在对象的生命早期定义mIgnoreBadCertificates委托 2.设置包含'beSecure'代码的属性为true 3.发送Http请求。 4.将属性设置为false。这非常重要,应该以保证调用它的方式实现。 IDisposable模式是一种选择。

 private System.Net.Security.RemoteCertificateValidationCallback mIgnoreBadCertificates = new
    System.Net.Security.RemoteCertificateValidationCallback(
      delegate { return true; });

if (beSecure)
    {   //require secure communications
        System.Net.ServicePointManager.ServerCertificateValidationCallback -= mIgnoreBadCertificates;
        Iwds.EventLogger.LogVeryFrequentEvent("Requiring Good Certificates from Remote Sites");
    }
    else
    {   /// Allow connections to SSL sites that have unsafe certificates.
        System.Net.ServicePointManager.ServerCertificateValidationCallback += mIgnoreBadCertificates;
        Iwds.EventLogger.LogVeryFrequentEvent("Ignoring Bad Certificates from Remote Sites");
    }

答案 2 :(得分:4)

解决问题的一个关键点是sender的{​​{1}}参数是RemoteCertificateValidationCallback。您可以根据您的网络请求检查发件人,这样您只需检查您的网络请求。这是我的(相对未经测试的)解决方案:

WebRequest

答案 3 :(得分:1)

public class OAuthRequestHandler : WebRequestHandler
{
    public OAuthRequestHandler() : base()
    {
        base.ServerCertificateValidationCallback  += this.InternalCallback;
    }

    private bool InternalCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        return certificate.Subject.Contains("CN=MyTrustedCompany.com");
    }
}

并在我的program.cs命令行测试中:

HttpClient client = new HttpClient(new OAuthRequestHandler());
responseString = await client.GetStringAsync("https://localhost:2345");

可以使用证书和发件人参数做更多事情,但OP要求提供上述内容。

答案 4 :(得分:0)

确保自定义回调可靠地还原并且确保线程安全的唯一可靠方法是将需要颠覆的回调的代码放入单独的进程中。在许多情况下,这很容易做到-例如,您可以使用Process类运行单独的过程代码,并将其传递给命令行。 gRPC或WCF是其他通信选项。

这样,只有单独的进程才能设置自定义回调,而主进程不受影响。

相关问题