【问题标题】:WCF connected service ServicePointManager.ServerCertificateValidationCallback not executedWCF 连接的服务 ServicePointManager.ServerCertificateValidationCallback 未执行
【发布时间】:2019-10-09 10:20:03
【问题描述】:

我在我的项目中添加了 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;
}

【问题讨论】:

  • 你试过设置ServicePointManager.SecurityProtocol吗?
  • 是的,我做了,没用。

标签: c# wcf soap-client servicepointmanager


【解决方案1】:

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

        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.");
            }
        }
    }

【讨论】:

  • 您好,X509CertificateValidator 是从哪个程序集继承而来的?
  • 没关系,我找到了。它是 System.IdentityModel.Selectors
【解决方案2】:
ServicePointManager.ServerCertificateValidationCallback += delegate
            {
                return true;
            };

此代码sn-p在Dotnetframework项目中有效,在Dotnet Core项目中无效。 一般在保证证书可信的情况下,应该将服务器提供的证书安装到客户端的Root CA证书库中。

另外,以下代码sn-p适用于DotNet Core项目和Dotnetframework项目。

ServiceReference1.TestServiceClient client = new ServiceReference1.TestServiceClient();
        client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = new System.ServiceModel.Security.X509ServiceCertificateAuthentication
        {
            CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None,
            RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
        };

如果问题仍然存在,请随时告诉我。

【讨论】:

  • 抱歉,我不能破坏旧功能。正如我提到的(就像浏览器一样),应用程序必须处理用户交互的证书问题。设置受信任的认证不是我问题的答案。但事实上,该回调在 .net 核心上不起作用非常有用,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-09
  • 1970-01-01
相关资源
最近更新 更多