2017-05-09 160 views
0

我需要实现一种方法来检查Web服务是否可用。 主要问题是URL是HTTPS,而需要证书。 所以我需要从机器获取证书,然后创建一个HttpWebRequest以获得HttpWebResponse检查HTTPS Web服务是否可用HttpWebRequest和X509 SSL证书

用我的实际执行情况,我可以检索证书,但是当我打电话request.GetResponse()方法时抛出此异常:

[System.Net.WebException] = {“基础连接已经关闭:发生意外错误在发送 “}

的InnerException:

[System.IO.IOException] = {” 从收到一条意外EOF或0字节传输流“}

我读了很多可能的解决方案,但似乎没有为我工作。 我在.NET 3.5

这是我的代码

using (WebClient client = new WebClient()) 
{ 
    X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
    store.Open(OpenFlags.ReadOnly); 
    X509Certificate2Collection certificates = store.Certificates.Find(X509FindType.FindByThumbprint, CertificateThumbprint, false); 

    if (certificates.Count == 0) 
     throw new Exception("No corresponding certificate found."); 

    X509Certificate2 certificate = certificates[0]; 

    // Not compiling on .NET 3.5 
    // Error: cannot apply '+=' operator to 
    //'System.Net.Security.RemoteCertificateValidationCallback' 
    //and 'anonymous method' 
    //ServicePointManager.ServerCertificateValidationCallback += 
    // delegate(
    //  object sender, 
    //  X509Certificate certificate, 
    //  X509Chain chain, 
    //  SslPolicyErrors sslPolicyErrors) 
    // { 
    //  return true; 
    // }; 

    // Not compiling on .NET 3.5 
    // Error: cannot apply '+=' operator to 'System.Net.Security.RemoteCertificateValidationCallback' and 'lambda expression' 
    // ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; 

    // Not working 
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; 

    // Not working 
    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(UrlWSInvioComunicazioni); 
    request.ClientCertificates.Add(certificate); 
    request.Method = "HEAD"; 

    // throws Exception... 
    HttpWebResponse webResponse = request.GetResponse() as HttpWebResponse; 
    webResponse.Close(); 

    response.ResultCode = ResultCode.Success; 
    response.ResultMessage = "Service available."; 
} 

更新2017年5月10日

因为我在.NET 3.5 TLS 1.2,我使用的是不支持来自Microsoft的修补程序(请参阅KB3154519),该修补程序可以使用SecurityProtocolTypeExtensionsSslProtocolsExtensions扩展类来使用TLS 1.2。

自2017年1月以来(当微软发布该修补程序时),我已经将该方法与其他一些Web服务一起使用,并且没有任何问题。

我认为,我现在有问题:

[System.Net.WebException] = { “请求被中止:无法创建SSL/TLS安全通道”}

必须与我的电脑中的东西。

更新2017年5月12日

我终于发现,问题是有关IIS。我的PC上的Web应用程序的应用程序池运行的身份设置为ApplicationPoolIdentity。当设置为LocalSystem或我当前的用户(管理员),它的工作。

因此,我认为应用程序池作为ApplicationPoolIdentity运行时,具有访问证书的内容不正确。

回答

1

扫描URL以查看服务器正在使用的SSL提供程序。你可以在这里 - >https://www.ssllabs.com/ssltest/analyze.html

protocols

一些服务器出于安全考虑禁用SSL3。因此,您必须改用此设置:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls; 

或者在客户端上使用Tls 1.2 if。

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls12; 

更新 检查这些代码是为你工作

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | (SecurityProtocolType)3072; 
var httpRequest = (HttpWebRequest)WebRequest.Create("https://google.com"); 
httpRequest.Method = "GET"; 
httpRequest.ContentType = "text/html"; 

httpRequest.KeepAlive = false; 
httpRequest.MaximumAutomaticRedirections = 30; 

var httpResponse = (HttpWebResponse)httpRequest.GetResponse(); 
var responseStream = new StreamReader(httpResponse.GetResponseStream()); 

var strResponse = responseStream.ReadToEnd(); 

httpResponse.Close(); 
responseStream.Close(); 
+0

谢谢你的提示!伟大的网站! ;-)似乎只使用TLS 1.2([link](https://www.ssllabs.com/ssltest/analyze.html?d=testservizi.fatturapa.it))。但在我的代码中,我只有'SecurityProtocolType.Ssl3'和'SecurityProtocolType.Tls'而不是'SecurityProtocolType.Tls12'。那么我能做什么......? –

+0

SLL提供程序安装在操作系统上,因此您必须检查系统上安装的提供程序。使用[IISCrypto](https://www.nartac.com/Products/IISCrypto)它会告诉你可以使用哪些提供程序。如果没有安装Tls 1.2,则必须更改操作系统。 Windows Server 2008 R2是第一个支持tls 1.2的窗口。 – migabriel

+0

我在Windows 10最新版本。但我使用VS 2012和.NET 3.5。 –