Échec sur HttpWebrequest avec exception interne L'authentification a échoué parce que la partie distante a fermé le flux de transport
en utilisant C#, .Net 4.5, j'essaie d'envoyer une requête web via HttpWebRequest sur un serveur distant. Veuillez voir le code ci-dessous. J'ai essayé la plupart des solutions suggérées par certains forums mais je finis toujours avec la même erreur. Consultez la trace de la pile ci-dessous. L'erreur est générée lors de l'appel de la demande.Méthode GetReponse ().
informations supplémentaires, essentiellement, j'essaie d'appeler la fonction reloadSslCertificate du composant vCenter de vmware installé sur un serveur distant. Actuellement, l'erreur ne se produit que sur vCenter 5.5. Il fonctionne très bien dans les versions 5.1 et suivantes.
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: Système.Net.WebException: la connexion sous-jacente était fermée: Une erreur inattendue s'est produite lors de l'envoi. ---> Système.IO.IOException: L'authentification a échoué parce que la partie distante a fermé le flux de transport. à Système.Net.Sécurité.SslState.StartReadFrame (Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) à Système.Net.Sécurité.SslState.Startreceiveblob (Byte[] buffer, AsyncProtocolRequest asyncRequest) à Système.Net.Sécurité.SslState.CheckCompletionBeforeNextReceive (ProtocolToken) message, AsyncProtocolRequest asyncRequest) à Système.Net.Sécurité.SslState.StartSendBlob (Byte[] incoming, Int32 compte, AsyncProtocolRequest asyncRequest) Système.Net.De sécurité.SslState.ForceAuthentication(Boolean receiveFirst, Byte [] buffer, AsyncProtocolRequest asyncRequest) à Système.Net.Sécurité.SslState.Processus D'Authentification(LazyAsyncResult lazyResult) au système.Net.TlsStream.Procédure D'Appelauthentication(Objet de l'état) à Système.Le filetage.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback rappel, état de l'Objet, Boolean preservesynctx) à Système.Le filetage.ExecutionContext.Run (ExecutionContext) executionContext, ContextCallback rappel, état de l'Objet, Boolean preservesynctx) à Système.Le filetage.ExecutionContext.Run (ExecutionContext) executionContext, ContextCallback rappel, l'état de l'Objet) à Système.Net.TlsStream.Processus d'authentification (résultat LazyAsyncResult) à Système.Net.TlsStream.Write (byte [] buffer, Int32 offset, Int32 size) at Système.Net.PooledStream.Write (byte [] buffer, Int32 offset, Int32 size) at System.Net.ConnectStream.WriteHeaders (Boolean async) - - - fin de trace de la pile d'exceptions internes - - - at Système.Net.HttpWebRequest.GetResponse()
Merci d'avance.
3 réponses
je veux juste partager que ce problème a déjà été résolu.
je viens de modifier la partie du code où je mets le protocole de sécurité avant d'émettre la demande web.
:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
À:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;
comme il s'est avéré, vCenter 5.5 utilise TLS comme protocole SSL dans sa configuration. J'espère que les gens trouveront cela utile lorsqu'ils seront confrontés à cette même question.
nous avons rencontré la même exception. Dans notre cas, la réponse était incroyablement similaire à la réponse de @Dennis Laping. Une autre équipe avait mis en place le service que nous essayions de frapper dans un Éleveur load balancer, qui par défaut ne permettait pas TLS 1.0 ou SSL3. Il arrive, la valeur par défaut de SecurityProtocol (sans le définir) dans .NET n'autorise que TLS 1.0 ou SSL3.
dès Que nous avons mis le SecurityProtocol comme suit, tout a bien fonctionné:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
Tout cela étant dit, la documentation de SecurityProtocol états:
votre code ne devrait jamais dépendre implicitement de l'utilisation d'un niveau de protection particulier, ou de l'hypothèse qu'un niveau de sécurité donné est utilisé par défaut. Si votre application dépend de l'utilisation d'un niveau de sécurité particulier, vous devez explicitement spécifier ce niveau et ensuite vérifier pour être sûr qu'il est réellement utilisé sur la connexion établie. De plus, votre code devrait être conçu pour être robuste face aux changements auxquels les protocoles sont supportés, car ces changements sont souvent effectués avec peu de préavis afin d'atténuer les menaces émergentes.
nous allons réévaluer Quelle est la meilleure solution à notre situation de protocole, mais pour l'instant j'espère que cela aidera quelqu'un d'autre.
Voir ce lien, il a travaillé pour moi: comment faire les HTTPS avec TcpClient comme le fait 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
P.S.
j'ai inséré cette ligne de code avant juste pour être sûr que le certificat côté serveur est accepté: ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3