C# HttpWebrequest 失败,内部异常身份验证失败,因为远程方已关闭传输流
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19639846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Failure on HttpWebrequest with inner exception Authentication failed because the remote party has closed the transport stream
提问by spitfyr86
Using C#, .Net 4.5, I'm trying to send out a web request through HttpWebRequest on a remote server. Please see the code below. I tried most of the solutions suggested by some forums but I always end up with the same error. Please see the stack trace below. The error is thrown when calling the request.GetReponse() method.
使用 C#、.Net 4.5,我试图通过远程服务器上的 HttpWebRequest 发送 Web 请求。请看下面的代码。我尝试了一些论坛建议的大多数解决方案,但最终总是出现相同的错误。请参阅下面的堆栈跟踪。调用 request.GetReponse() 方法时抛出错误。
Additional info, basically, I'm trying to call the reloadSslCertificate function of vmware's vCenter component installed on a remote server. Currently, the error only happens on vCenter 5.5. It works fine in versions 5.1 and below.
附加信息,基本上,我试图调用安装在远程服务器上的 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();
Exception : System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Authentication failed because the remote party has closed the transport stream. at 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 message, AsyncProtocolRequest asyncRequest) at 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 state) at 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 inner exception stack trace --- at System.Net.HttpWebRequest.GetResponse()
异常:System.Net.WebException:基础连接已关闭:发送时发生意外错误。---> 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 message, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartSendBlob(Byte[]coming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState。
Thanks in advance.
提前致谢。
采纳答案by spitfyr86
I just want to share that this issue has already been resolved.
我只想分享这个问题已经解决了。
I just modified the part of the code where I set the security protocol before issuing the web request.
我只是修改了在发出 Web 请求之前设置安全协议的代码部分。
From:
从:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
To:
到:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;
As it turned out, vCenter 5.5 uses TLS as its SSL protocol in its configuration. I hope people may find this helpful when they encounter this same issue.
事实证明,vCenter 5.5 在其配置中使用 TLS 作为其 SSL 协议。我希望人们在遇到同样的问题时会发现这很有帮助。
回答by MaGnumX
See this link, it worked for me: How to do HTTPS with TcpClient just like HttpWebRequest does?
看到这个链接,它对我有用: How to do HTTPS with TcpClient just like HttpWebRequest do?
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
P.S.
聚苯乙烯
I inserted this line of code before just to be sure that the certificate from the server side is accepted: ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
我之前插入了这行代码,只是为了确保接受来自服务器端的证书: ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
回答by neumann1990
We ran into the same exception. In our case, the answer was incredibly similar to @Dennis Laping's answer. Another team had setup the service we were trying to hit within a Rancherload balancer, which by default did not allow TLS 1.0 or SSL3. It just so happens the current default for SecurityProtocol(without setting it) in .NET only allows TLS 1.0 or SSL3.
我们遇到了同样的异常。在我们的案例中,答案与@Dennis Laping 的答案非常相似。另一个团队设置了我们试图在Rancher负载均衡器中访问的服务,默认情况下不允许 TLS 1.0 或 SSL3。碰巧.NET 中SecurityProtocol(未设置)的当前默认值仅允许 TLS 1.0 或 SSL3。
As soon as we set the SecurityProtocolas follows, everything worked fine:
一旦我们将SecurityProtocol设置为如下,一切正常:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
All that being said, the documentation for SecurityProtocolstates that:
话虽如此,SecurityProtocol的文档指出:
Your code should never implicitly depend on using a particular protection level, or on the assumption that a given security level is used by default. If your app depends on the use of a particular security level, you must explicitly specify that level and then check to be sure that it is actually in use on the established connection. Further, your code should be designed to be robust in the face of changes to which protocols are supported, as such changes are often made with little advance notice in order to mitigate emerging threats.
您的代码不应隐含地依赖于使用特定的保护级别,或假设默认情况下使用给定的安全级别。如果您的应用程序依赖于特定安全级别的使用,您必须明确指定该级别,然后检查以确保它确实在已建立的连接上使用。此外,您的代码应设计为在面对所支持协议的更改时具有健壮性,因为此类更改通常在很少提前通知的情况下进行,以减轻新出现的威胁。
We'll be reevaluating what the best solution is to our protocol situation, but for now I hope this helps someone else.
我们将重新评估我们的协议情况的最佳解决方案,但现在我希望这对其他人有所帮助。