【问题标题】:How to invoke a Web Service which requires a certificate in C#?如何在 C# 中调用需要证书的 Web 服务?
【发布时间】:2016-07-10 22:13:33
【问题描述】:

我需要与拥有.asmx 网络服务的第三方通信。此 Web 服务使用 https。我有所需的证书 (.pfx)。

第一次尝试在 Visual Studio 中使用 Add Service Reference 添加此服务时,出现错误。我通过将证书导入Personal 商店而通过了这个错误。在我这样做之后,我尝试再次添加服务引用并且它有效。所以现在我可以创建 Web 服务的实例。不错。

但现在我想调用服务。当我这样做时,我得到了这个错误:

302 通知:数字证书丢失

那么我怎样才能告诉我的服务使用正确的证书呢?

【问题讨论】:

    标签: c# visual-studio web-services certificate


    【解决方案1】:

    我终于设法解决了我的问题:

    var service = new Service1SoapClient();
    service.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.TrustedPublisher, X509FindType.FindByIssuerName, "name_of_issuer");
    ((BasicHttpBinding)service.Endpoint.Binding).Security.Mode = BasicHttpSecurityMode.Transport;
    ((BasicHttpBinding)service.Endpoint.Binding).Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
    

    请使用 Certificate.pfx 并使用密码安装。

    【讨论】:

    • 如果引用有问题,您需要添加。使用 System.Security.Cryptography.X509Certificates
    【解决方案2】:

    在获取请求流之前尝试添加:

    ServicePointManager.Expect100Continue = true;
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
    request.ProtocolVersion = HttpVersion.Version10;
    request.ClientCertificates.Add(new X509Certificate2("YourPfxFile(full path).pfx", "password for your pfx file");
    

    根据您的安全要求和环境,您可能需要使用不同的 SecurityProrocolType 值。

    【讨论】:

    • 感谢您的回答,但我的服务中没有 ClientCertificates 的属性:var service = new Service1.Service1SoapClient();
    • 在 SOAP 服务调用的情况下,这需要添加到生成的代理类 Reference.cs 中。唯一的问题是,一旦您修改了此类,更新 Web 引用将重新编写生成的代理,您将需要重新应用手动修改。
    • 这对我来说是新的。我找到了Reference.cs 文件,但是我需要在该文件的哪个位置使用此代码?文件很大(370行代码)
    • 它需要进入您调用的方法才能向服务发送请求。
    • 在该方法中没有具有属性ClientCertificates 的变量,也没有“ProtocolVersion”。 SsoPocV2.RaetService.GetXSSORequest inValue = new SsoPocV2.RaetService.GetXSSORequest(); inValue.Body = new SsoPocV2.RaetService.GetXSSORequestBody(); inValue.Body.xmlstr = xmlstr; SsoPocV2.RaetService.GetXSSOResponse retVal = ((SsoPocV2.RaetService.Service1Soap)(this)).GetXSSO(inValue); return retVal.Body.GetXSSOResult;
    【解决方案3】:

    在请求 Web 服务时,我还面临“请求被中止:无法创建 SSL/TLS 安全通道”的问题。 修复了以下代码的问题,希望这对某人有所帮助并节省时间。

     HttpWebRequest web_request = (HttpWebRequest)WebRequest.Create("https://yourservices/test.asmx");
            web_request.ContentType = "text/xml;charset=\"utf-8\"";
    
            ServicePointManager.Expect100Continue = true;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
            web_request.ProtocolVersion = HttpVersion.Version10;
    
            X509Certificate2Collection certificates = new X509Certificate2Collection();
            certificates.Import(certName, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
    
            web_request.ClientCertificates = certificates;
            web_request.Accept = "text/xml";
            web_request.Method = "POST";
    
            using (Stream stm = web_request.GetRequestStream())
            {
                using (StreamWriter stmw = new StreamWriter(stm))
                {
                    stmw.Write(soap);
                }
            }
    
            WebResponse web_response = null;
            StreamReader reader = null;
    
            try
            {
                web_response = web_request.GetResponse();
                Stream responseStream = web_response.GetResponseStream();
                XmlDocument xml = new XmlDocument();
    
                reader = new StreamReader(responseStream);
                xml.LoadXml(reader.ReadToEnd());
            }
            catch (Exception webExp) {
                string exMessage = webExp.Message;
            }
    

    【讨论】:

      猜你喜欢
      • 2020-04-14
      • 2019-01-31
      • 1970-01-01
      • 1970-01-01
      • 2013-11-11
      • 2020-10-03
      • 2019-05-23
      • 2011-05-22
      • 1970-01-01
      相关资源
      最近更新 更多