首页 > 解决方案 > WCF 连接的服务 ServicePointManager.ServerCertificateValidationCallback 未执行

问题描述

我在我的项目中添加了 WCF 连接服务引用并设置ServicePointManager.ServerCertificateValidationCallback功能。由于某种原因,当我请求服务器时,此回调函数被忽略。如果用户确认,我必须通知用户证书问题并继续请求。

static async Task Main(string[] args)
{
    ServicePointManager.ServerCertificateValidationCallback = MyServerCertificateValidationCallback;
    var data = new DataSoapClient(DataSoapClient.EndpointConfiguration.DataSoap);
    data.Endpoint.Address = new EndpointAddress("https://open.helios.eu/demo/Data.asmx");
    (data.Endpoint.Binding as BasicHttpBinding).Security.Mode = BasicHttpSecurityMode.Transport;
    var result = (await data.GetInfoAsync("GETREDIRECTINFO", string.Empty)).Body.GetInfoResult;
    Console.WriteLine(result);
}

private static bool MyServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    // function won't execute
    return true;
}

标签: c#wcfsoap-clientservicepointmanager

解决方案


最后我找到了解决我的问题的方法。正如 Abraham Quan 所提到的,回调在 .net 核心中不起作用,所以我不得不使用不同的方法并使用 X509CertificateValidator。这是一个代码片段:

        static async Task Main(string[] args)
        {
            var data = new ServiceReference1.Service1Client(Service1Client.EndpointConfiguration.BasicHttpsBinding_IService1);
            data.Endpoint.Address = new EndpointAddress("https://localhost:5035/Service1.svc");
            (data.Endpoint.Binding as BasicHttpBinding).Security.Mode = BasicHttpSecurityMode.Transport;

            data.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication();
            data.ClientCredentials.ServiceCertificate.SslCertificateAuthentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
            data.ClientCredentials.ServiceCertificate.SslCertificateAuthentication.CustomCertificateValidator = new Validator();

            var result = await data.GetDataAsync(1);
            Console.WriteLine(result);
        }

并且有验证器:

    internal class Validator : X509CertificateValidator
    {
        public override void Validate(X509Certificate2 certificate)
        {
            X509Chain chain = new X509Chain();
            if (!chain.Build(certificate))
            {
                Console.WriteLine($"{chain.ChainStatus.FirstOrDefault().StatusInformation}. Press y to proceed...");
                if(Console.ReadKey().KeyChar != 'y')
                    throw new SecurityTokenValidationException("Service certification is not valid.");
            }
        }
    }

推荐阅读