HttpWebrequest 失败,内部异常 身份验证失败,因为远程方已关闭传输流

本文关键字:失败 传输 异常 内部 身份验证 因为 HttpWebrequest | 更新日期: 2023-09-27 18:37:20

使用C#,.Net 4.5,我正在尝试通过远程服务器上的HttpWebRequest发送Web请求。请参阅下面的代码。我尝试了一些论坛建议的大多数解决方案,但我总是以相同的错误告终。请参阅下面的堆栈跟踪。调用请求时引发错误。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.Web异常:基础连接是 已关闭:发送时发生意外错误。---> System.IO.IOException:身份验证失败,因为远程方 已关闭传输流。在 System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken 消息, 异步协议请求 异步请求) 在 System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.TlsStream.CallProcessAuthentication(Object 状态)在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result) at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size) at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size) at System.Net.ConnectStream.WriteHeaders(Boolean async) --- End of 内部异常堆栈跟踪--- System.Net.HttpWebRequest.GetResponse()

提前谢谢。

HttpWebrequest 失败,内部异常 身份验证失败,因为远程方已关闭传输流

我只想分享这个问题已经解决。

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

从:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

自:

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

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

我们遇到了同样的异常。在我们的案例中,答案与@Dennis Laping的答案非常相似。另一个团队在Rancher负载均衡器中设置了我们尝试使用的服务,默认情况下不允许TLS 1.0或SSL3。碰巧的是,.NET 中安全协议的当前默认值(未设置)仅允许 TLS 1.0 或 SSL3。

一旦我们按如下方式设置安全协议,一切正常:

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

话虽如此,安全协议的文档指出:

代码绝不应隐式依赖于使用

特定的保护级别,也不应隐式依赖于默认使用给定安全级别的假设。如果你的应用依赖于特定安全级别的使用,则必须显式指定该级别,然后检查以确保它确实在已建立的连接上使用。此外,您的代码应设计为在面对支持协议的更改时具有健壮性,因为此类更改通常在几乎没有提前通知的情况下进行,以缓解新出现的威胁。

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

看到这个链接,它对我有用:如何使用TcpClient进行HTTPS,就像HttpWebRequest一样?

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