Problème: je reçois cette exception "LA CONNEXION SOUS-JACENTE A ÉTÉ FERMÉE: UNE ERREUR INATTENDUE SE PRODUIT SUR UN ENVOI" dans mes journaux et brise notre intégration OEM avec notre système de marketing par courrier électronique à des moments aléatoires variant de [1 heure à 4 heures].
Mon site Web est hébergé sur un Windows Server 2008 R2 avec IIS 7.5.7600. Ce site Web contient un grand nombre de composants OEM et un tableau de bord complet. Tout fonctionne bien avec tous les autres éléments du site Web, à l’exception de l’un de nos composants de marketing par courriel, que nous utilisons comme solution iframe dans notre tableau de bord. La façon dont cela fonctionne est, j'envoie un httpWebRequestobject avec toutes les informations d'identification et je récupère une URL que je mets dans un iframe et cela fonctionne. Mais cela ne fonctionne que pendant un certain temps [1 heure - 4 heures] et puis j'obtiens l'exception ci-dessous "LA CONNEXION SOUS-JACENTÉE A ÉTÉ FERMÉE: UNE ERREUR INATTENDUE SURVENUE SUR UN ENVOI" et même si le système tente d'obtenir l'URL du httpWebRequest échoue avec la même exception. Le seul moyen de le faire fonctionner à nouveau est de recycler le pool d'applications ou tout élément est modifié dans web.config. Je suis vraiment épuisé toute l'option que je pouvais penser.
Explicitement ajouté, keep-alive = false
keep-alive = true
Augmentation du délai d'attente: <httpRuntime maxRequestLength="2097151" executionTimeout="9999999" enable="true" requestValidationMode="2.0" />
J'ai téléchargé cette page sur un site Web autre que SSL pour vérifier si le certificat SSL de notre serveur de production établit la connexion pour supprimer un peu comment.
Toute orientation vers la résolution est grandement appréciée.
Code:
Public Function CreateHttpRequestJson(ByVal url) As String
Try
Dim result As String = String.Empty
Dim httpWebRequest = DirectCast(WebRequest.Create("https://api.xxxxxxxxxxx.com/api/v3/externalsession.json"), HttpWebRequest)
httpWebRequest.ContentType = "text/json"
httpWebRequest.Method = "PUT"
httpWebRequest.ContentType = "application/x-www-form-urlencoded"
httpWebRequest.KeepAlive = False
'ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
'TODO change the integratorID to the serviceproviders account Id, useremail
Using streamWriter = New StreamWriter(httpWebRequest.GetRequestStream())
Dim json As String = New JavaScriptSerializer().Serialize(New With { _
Key .Email = useremail, _
Key .Chrome = "None", _
Key .Url = url, _
Key .IntegratorID = userIntegratorID, _
Key .ClientID = clientIdGlobal _
})
'TODO move it to the web.config, Following API Key is holonis accounts API Key
SetBasicAuthHeader(httpWebRequest, holonisApiKey, "")
streamWriter.Write(json)
streamWriter.Flush()
streamWriter.Close()
Dim httpResponse = DirectCast(httpWebRequest.GetResponse(), HttpWebResponse)
Using streamReader = New StreamReader(httpResponse.GetResponseStream())
result = streamReader.ReadToEnd()
result = result.Split(New [Char]() {":"})(2)
result = "https:" & result.Substring(0, result.Length - 2)
End Using
End Using
Me.midFrame.Attributes("src") = result
Catch ex As Exception
objLog.WriteLog("Error:" & ex.Message)
If (ex.Message.ToString().Contains("Invalid Email")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Email Taken")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Invalid Access Level")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Unsafe Password")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Invalid Password")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Empty Person Name")) Then
'TODO Show message on UI
End If
End Try
End Function
Public Sub SetBasicAuthHeader(ByVal request As WebRequest, ByVal userName As [String], ByVal userPassword As [String])
Dim authInfo As String = Convert.ToString(userName) & ":" & Convert.ToString(userPassword)
authInfo = Convert.ToBase64String(Encoding.[Default].GetBytes(authInfo))
request.Headers("Authorization") = "Basic " & authInfo
End Sub`
Pour moi c'était tls12:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Si vous êtes bloqué avec .Net 4.0 et que le site cible utilise TLS 1.2, vous avez plutôt besoin de la ligne suivante. ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
source: Support TLS 1.2 et .NET: Comment éviter les erreurs de connexion
Le code ci-dessous a résolu le problème
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls Or SecurityProtocolType.Ssl3
Dans mon cas, le site auquel je me connecte a été mis à niveau vers TLS 1.2. En conséquence, j'ai dû installer .net 4.5.2 sur mon serveur Web pour pouvoir le prendre en charge.
Cela fait plusieurs jours que je rencontre le même problème avec une intégration qui, elle aussi, "fonctionnait auparavant".
Hors de la dépression, je viens d'essayer
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
Cela a résolu le problème pour moi. Même si l'intégration utilise uniquement SSLv3.
Je me suis rendu compte que quelque chose n'allait pas depuis que Fiddler avait déclaré qu'il existait un "chiffrement de négociation TLS vide" ou quelque chose du genre.
Espérons que cela fonctionne!
Accédez à votre web.config/App.config pour vérifier le runtime .net que vous utilisez.
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
Voici la solution:
.NET 4.6 et supérieur. Vous n'avez pas besoin de faire de travail supplémentaire pour prendre en charge TLS 1.2, cela est pris en charge par défaut.
.NET 4.5. TLS 1.2 est pris en charge, mais ce n’est pas un protocole par défaut. Vous devez choisir de l'utiliser. Le code suivant rendra TLS 1.2 par défaut, assurez-vous de l'exécuter avant de vous connecter à une ressource sécurisée:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
J'ai constaté que cela indique que le serveur sur lequel vous déployez du code dispose d'un ancien framework .NET installé qui ne prend pas en charge TLS 1.1 ou TLS 1.2. Étapes à suivre:
Vous pouvez obtenir les derniers .NET Developer Pack et Runtime à partir de cette URL: http://getdotnet.azurewebsites.net/target-dotnet-platforms.html
Nous avons eu ce problème par lequel un site Web qui accédait à notre API recevait le message "La connexion sous-jacente était fermée: une erreur inattendue s'est produite lors de l'envoi".
Leur code était un mélange de .NET 3.x et 2.2, ce qui, si j'ai bien compris, signifie qu'ils utilisent TLS 1.0.
La réponse ci-dessous peut vous aider à diagnostiquer le problème en activant TLS 1.0, SSL 2 et SSL3, mais pour être très clair, vous ne voulez pas le faire à long terme, car ces trois protocoles sont considérés comme peu sûrs et ne doit plus être utilisé:
Pour que notre IIS réponde à leurs appels d'API, nous devions ajouter des paramètres de registre sur le serveur IIS afin d'activer explicitement les versions de TLS - REMARQUE: vous devez redémarrer le serveur Windows (pas uniquement le IIS service) après avoir effectué les modifications suivantes:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.0\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.0\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.1\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.1\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
Si cela ne le fait pas, vous pouvez également expérimenter l'ajout de l'entrée pour SSL 2.0:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001
Pour être clair, ce n’est pas une solution intéressante , et la bonne solution consiste à obliger l’appelant à utiliser TLS 1.2, mais ce qui précède peut aider à diagnostiquer ce problème. c'est le problème.
Vous pouvez accélérer l’ajout de ces entrées reg avec ce script powershell:
$ProtocolList = @("SSL 2.0","SSL 3.0","TLS 1.0", "TLS 1.1", "TLS 1.2")
$ProtocolSubKeyList = @("Client", "Server")
$DisabledByDefault = "DisabledByDefault"
$Enabled = "Enabled"
$registryPath = "HKLM:\\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\"
foreach($Protocol in $ProtocolList)
{
Write-Host " In 1st For loop"
foreach($key in $ProtocolSubKeyList)
{
$currentRegPath = $registryPath + $Protocol + "\" + $key
Write-Host " Current Registry Path $currentRegPath"
if(!(Test-Path $currentRegPath))
{
Write-Host "creating the registry"
New-Item -Path $currentRegPath -Force | out-Null
}
Write-Host "Adding protocol"
New-ItemProperty -Path $currentRegPath -Name $DisabledByDefault -Value "0" -PropertyType DWORD -Force | Out-Null
New-ItemProperty -Path $currentRegPath -Name $Enabled -Value "1" -PropertyType DWORD -Force | Out-Null
}
}
Exit 0
Il s'agit d'une version modifiée du script de la page d'aide de Microsoft pour Configurer TLS pour VMM . Cet article basics.net était la page qui m'a donné l'idée de regarder ces paramètres.
Il suffit d'ajouter:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Cela peut être causé par l’utilisation d’un proxy de débogage HTTP, tel que Fiddler.
Je chargeais un certificat PFX à partir d'un fichier local (authentification sur Apple.com) et cela a échoué car Fiddler n'a pas pu transmettre ce certificat.
Essayez de désactiver Fiddler pour vérifier et si telle est la solution, vous devez probablement installer le certificat sur votre ordinateur ou utiliser Fiddler d’une manière ou d’une autre.
Le code ci-dessous a résolu mon problème:
request.ProtocolVersion = HttpVersion.Version10; // THIS DOES THE TRICK
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
Vous venez de changer la version de votre application, comme 4.0 à 4.6, et publiez ce code.
Ajoutez également les lignes de code ci-dessous:
httpRequest.ProtocolVersion = HttpVersion.Version10;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
Il aide si quelqu'un, notre problème était avec un certificat manquant. L'environnement est Windows Server 2016 Standard avec .Net 4.6.
Il existe un URI https du service WCF auto-hébergé, pour lequel Service.Open () s'exécuterait sans erreur. Un autre thread continuerait à accéder https: // OurIp: 443/OurService? Wsdl afin de s’assurer que le service était disponible. L'accès au WSDL utilisé pour échouer avec:
La connexion sous-jacente a été fermée: une erreur inattendue s'est produite lors d'un envoi.
L'utilisation de ServicePointManager.SecurityProtocol avec les paramètres applicables ne fonctionnait pas. Jouer avec les rôles de serveur et les fonctionnalités n'a pas aidé non plus. Puis, intervenez Jaise George , le SE, résolvant le problème en quelques minutes. Jaise a installé un certificat auto-signé dans IIS, corrigeant le problème. Voici ce qu'il a fait pour résoudre le problème:
(1) Ouvrez IIS manager (inetmgr) (2) Cliquez sur le nœud du serveur dans le panneau de gauche, puis double-cliquez sur "Certificats de serveur". (3) Cliquez sur "Créer un certificat auto-signé" dans le panneau de droite et tapez ce que vous voulez comme nom convivial. (4) Cliquez sur "Site Web par défaut" dans le panneau de gauche, cliquez sur "Liaisons" dans le panneau de droite, cliquez sur "Ajouter", sélectionnez "https", sélectionnez le certificat que vous venez de créer, puis cliquez sur "OK". (5) Accès l'URL https, il devrait être accessible.