【问题标题】:Failure on HttpWebrequest with inner exception Authentication failed because the remote party has closed the transport streamHttpWebrequest 失败,内部异常身份验证失败,因为远程方已关闭传输流
【发布时间】:2013-11-07 12:33:42
【问题描述】:

使用 C#、.Net 4.5,我正在尝试通过远程服务器上的 HttpWebRequest 发送 Web 请求。请看下面的代码。 我尝试了一些论坛建议的大多数解决方案,但我总是以同样的错误告终。请参阅下面的堆栈跟踪。 调用request.GetReponse()方法时抛出错误。

附加信息,基本上,我正在尝试调用安装在远程服务器上的 vmware 的 vCenter 组件的 reloadSslCertificate 函数。目前,该错误仅发生在 vCenter 5.5 上。它在 5.1 及以下版本中运行良好。

        var uri = String.Format("https://{0}/some_url", serverName);
        var request = (HttpWebRequest)WebRequest.Create(uri);
        request.KeepAlive = true;
        request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        request.Headers.Set(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.8");
        request.Credentials = credential;
        request.CookieContainer = cookieContainer;


        var response = request.GetResponse();

异常:System.Net.WebException:底层连接是 关闭:发送时发生意外错误。 ---> System.IO.IOException:身份验证失败,因为远程方 已关闭传输流。在 System.Net.Security.SslState.StartReadFrame(字节 [] 缓冲区,Int32 readBytes,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartReceiveBlob(字节 [] 缓冲区, AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(协议令牌 消息,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartSendBlob(字节 [] 传入,Int32 计数,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.ForceAuthentication(布尔接收第一, Byte[] 缓冲区,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) 在 System.Net.TlsStream.CallProcessAuthentication(Object 州)在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext、ContextCallback 回调、对象状态、布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback 回调、对象状态、布尔值 preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback 回调、对象状态)在 System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult 结果)在 System.Net.TlsStream.Write(Byte[] 缓冲区,Int32 偏移量,Int32 大小) 在 System.Net.PooledStream.Write(Byte[] 缓冲区,Int32 偏移量,Int32 大小) 在 System.Net.ConnectStream.WriteHeaders(Boolean async) --- 结束 内部异常堆栈跟踪 --- 在 System.Net.HttpWebRequest.GetResponse()

提前致谢。

【问题讨论】:

    标签: c# ssl-certificate vmware vcenter system.net.webexception


    【解决方案1】:

    我只是想分享一下这个问题已经解决了。

    我只是在发出 Web 请求之前修改了设置安全协议的代码部分。

    发件人:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
    

    收件人:

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

    事实证明,vCenter 5.5 在其配置中使用 TLS 作为其 SSL 协议。我希望人们在遇到同样的问题时会发现这很有帮助。

    【讨论】:

    • 赞成,因为这对我有很大帮助,但对其他人来说:还要检查是否有新版本可以附加在这里。为了我的需要,我需要 Tls12 而不是 Tls。
    • 如果我在尝试使用 CMD 生成代码时遇到此错误怎么办?
    【解决方案2】:

    我们遇到了同样的异常。在我们的案例中,答案与@Dennis Laping 的答案非常相似。另一个团队在 Rancher 负载均衡器中设置了我们试图访问的服务,默认情况下不允许 TLS 1.0 或 SSL3。 .NET 中 SecurityProtocol 的当前默认值(不设置它)仅允许 TLS 1.0 或 SSL3。

    只要我们将SecurityProtocol 设置如下,一切正常:

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

    话虽如此,SecurityProtocol 的文档指出:

    您的代码不应隐含地依赖于使用特定的保护级别,或者假设默认使用给定的安全级别。如果您的应用程序依赖于特定安全级别的使用,您必须明确指定该级别,然后检查以确保它确实在已建立的连接上使用。此外,您的代码应设计为在支持协议的更改时保持稳健,因为此类更改通常是在没有提前通知的情况下进行的,以减轻新出现的威胁。

    我们将重新评估针对我们的协议情况的最佳解决方案,但现在我希望这对其他人有所帮助。

    【讨论】:

    • +1 拯救了我的生命。为了让我们的服务在 ssllabs 上获得 A 评级,我们严格限制了端点允许的协议——破坏了我们的客户端应用程序。你的答案是解决它的诀窍!谢谢!!
    • 如果我在尝试使用 CMD 生成代码时遇到此错误怎么办?
    【解决方案3】:

    查看此链接,它对我有用: How to do HTTPS with TcpClient just like HttpWebRequest does?

    Dim trust_all_certificates As New CertificateOverride
    ServicePointManager.ServerCertificateValidationCallback = AddressOf trust_all_certificates.RemoteCertificateValidationCallback
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
    
    Public Class CertificateOverride
    
        Public Function RemoteCertificateValidationCallback(ByVal sender As Object, ByVal certificate As X509Certificate, ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
    
            'CertEXPIRED = 2148204801
            'CertVALIDITYPERIODNESTING = 2148204802
            'CertPATHLENCONST = 2148204804
            'CertROLE = 2148204803
            'CertCRITICAL = 2148204805
            'CertPURPOSE = 2148204806
            'CertISSUERCHAINING = 2148204807
            'CertMALFORMED = 2148204808
            'CertUNTRUSTEDROOT = 2148204809
            'CertCHAINING = 2148204810
            'CertREVOKED = 2148204812
            'CertUNTRUSTEDTESTROOT = 2148204813
            'CertREVOCATION_FAILURE = 2148204814
            'CertCN_NO_MATCH = 2148204815
            'CertWRONG_USAGE = 2148204816
            'CertUNTRUSTEDCA = 2148204818
    
            Return True
    
        End Function
    
    End Class
    

    附言

    我之前插入这行代码只是为了确保来自服务器端的证书被接受:ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3

    【讨论】:

    • 谢谢。我会试试的。
    • 如果我在尝试使用 CMD 生成代码时遇到此错误怎么办?
    • Zeeshan,你能给我们更多的信息吗?而且,我认为您应该提出一个新问题(如果不存在),因为我认为您遇到了另一种类型的“错误”。
    猜你喜欢
    • 2016-05-07
    • 2015-08-20
    • 1970-01-01
    • 2013-03-24
    • 2017-08-18
    • 2022-06-29
    • 2015-09-28
    • 1970-01-01
    相关资源
    最近更新 更多