Problema: recebo esta exceção "A CONEXÃO SUBJACENTE FOI FECHADA: UM ERRO INESPERADO OCORREU EM UM ENVIO" em meus registros e está interrompendo nossa integração de OEM com nosso sistema de e-mail marketing em horários aleatórios variando de [1 hora - 4 horas]
Meu site está hospedado em um servidor Windows 2008 R2 com IIS 7.5.7600. Este site possui um grande número de componentes OEM e um painel abrangente. Tudo funciona bem com todos os outros elementos do site, exceto com um de nossos componentes de marketing por e-mail, que estamos usando como uma solução iframe em nosso painel. Funciona assim: envio um objeto httpWebRequest com todas as credenciais e recebo de volta um url que coloquei em um iframe e funciona. Mas isso só funciona por algum tempo [1 hora - 4 horas] e então eu obtenho a exceção abaixo "A CONEXÃO SUBJACENTE FOI FECHADA: UM ERRO INESPERADO OCORREU EM UM ENVIO" e mesmo se o sistema tentar obter o URL do httpWebRequest falha com a mesma exceção. A única maneira de fazê-lo funcionar novamente é reciclar o pool de aplicativos ou qualquer coisa é editada em web.config.
Opção tentada
Adicionado explicitamente, keep-alive = false
keep-alive = true
Aumento do tempo limite: <httpRuntime maxRequestLength="2097151" executionTimeout="9999999" enable="true" requestValidationMode="2.0" />
Eu carreguei esta página para um site não SSL para verificar se o certificado SSL em nosso servidor de produção está fazendo a conexão para cair de alguma forma.
Qualquer direção para a resolução é muito apreciada.
Código:
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`
fonte
Respostas:
Para mim foi tls12:
fonte
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls
Se você estiver preso com .Net 4.0 e o site de destino estiver usando TLS 1.2, você precisará da seguinte linha.
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
fonte: TLS 1.2 e suporte .NET: como evitar erros de conexão
fonte
(SecurityProtocolType)768
pode ser usado para "Tls11" (ou seja, TLS 1.1).O código abaixo resolveu o problema
fonte
ServicePointManager.SecurityProtocol
é um objeto estático, o que significa que a alteração desse valor afetará todas as subseqüênciasWebRequest
ouWebClient
chamadas. Você pode criar separadoAppDomain
se quiserServicePointManager
ter configurações diferentes. Consulte stackoverflow.com/questions/3791629/… para obter mais detalhes.Estou tendo o mesmo problema há dias com uma integração que também "costumava funcionar antes".
Por pura depressão, eu apenas tentei
Isso resolveu para mim ... embora a integração estritamente apenas faça uso de SSLv3.
Cheguei à conclusão de que algo estava errado desde que o Fiddler relatou que há uma "cifra de negociação TLS vazia" ou algo parecido.
Espero que funcione!
fonte
No meu caso, o site ao qual estou me conectando foi atualizado para o TLS 1.2. Como resultado, tive que instalar o .net 4.5.2 no meu servidor web para suportá-lo.
fonte
Acesse seu web.config / App.config para verificar qual .net runtime você está usando
Aqui está a solução:
.NET 4.6 e superior. Você não precisa fazer nenhum trabalho adicional para oferecer suporte a TLS 1.2, ele é compatível por padrão.
.NET 4.5. TLS 1.2 é compatível, mas não é um protocolo padrão. Você precisa optar por usá-lo. O código a seguir tornará o TLS 1.2 padrão, certifique-se de executá-lo antes de fazer uma conexão com o recurso seguro:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
fonte
Descobri que isso é um sinal de que o servidor onde você está implantando o código tem um antigo .NET framework instalado que não oferece suporte a TLS 1.1 ou TLS 1.2. Passos para corrigir:
Você pode obter o .NET Developer Pack e o Runtime mais recentes neste URL: http://getdotnet.azurewebsites.net/target-dotnet-platforms.html
fonte
Tivemos esse problema em que um site que estava acessando nossa API recebia a mensagem “A conexão subjacente foi fechada: Ocorreu um erro inesperado em um envio”. mensagem.
O código deles era uma mistura de .NET 3.xe 2.2, o que, pelo que entendi, significa que eles estão usando TLS 1.0.
A resposta abaixo pode ajudá-lo a diagnosticar o problema ativando TLS 1.0, SSL 2 e SSL3, mas para ser muito claro, você não quer fazer isso a longo prazo, pois todos os três protocolos são considerados inseguros e não deveriam mais ser usado :
Para fazer o nosso IIS responder às suas chamadas de API, tivemos que adicionar configurações de registro no servidor do IIS para habilitar explicitamente as versões do TLS - NOTA: Você deve reiniciar o servidor Windows (não apenas o serviço IIS) depois de fazer essas alterações:
Se isso não funcionar, você também pode experimentar adicionar a entrada para SSL 2.0:
Para ser claro, essa não é uma boa solução , e a solução certa é fazer o chamador usar o TLS 1.2, mas o que foi dito acima pode ajudar a diagnosticar que esse é o problema.
Você pode adicionar rapidamente essas entradas de registro com este script do PowerShell:
Essa é uma versão modificada do script da página de ajuda da Microsoft para Configurar TLS para VMM . Este artigo do basics.net foi a página que originalmente me deu a ideia de examinar essas configurações.
fonte
Basta adicionar:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
fonte
Se ajudar alguém, nosso problema foi com falta de certificado. O ambiente é Windows Server 2016 Standard com .Net 4.6.
Há um URI https de serviço WCF auto-hospedado, para o qual Service.Open () seria executado sem erros. Outro encadeamento continuaria acessando https: // OurIp: 443 / OurService? Wsdl para garantir que o serviço estivesse disponível. Acessar o WSDL costumava falhar com:
A conexão subjacente foi fechada: Ocorreu um erro inesperado em um envio.
Usar ServicePointManager.SecurityProtocol com configurações aplicáveis não funcionou. Jogar com funções e recursos do servidor também não ajudou. Em seguida, interveio Jaise George , o SE, resolvendo o problema em alguns minutos. Jaise instalou um certificado autoassinado no IIS, resolvendo o problema. Isso é o que ele fez para resolver o problema:
(1) Abra o gerenciador IIS (inetmgr) (2) Clique no nó do servidor no painel esquerdo e clique duas vezes em "Certificados do servidor". (3) Clique em "Criar certificado autoassinado" no painel direito e digite o que quiser para o nome amigável. (4) Clique em “Site padrão” no painel esquerdo, clique em "Ligações" no painel direito, clique em "Adicionar", selecione "https", selecione o certificado que você acabou de criar e clique em "OK" (5) Acesso o URL https, deve estar acessível.
fonte
Basta alterar a versão do aplicativo, como 4.0 para 4.6, e publicar esse código.
Adicione também as linhas de código abaixo:
fonte
Usar um proxy de depuração HTTP pode causar isso - como o Fiddler.
Eu estava carregando um certificado PFX de um arquivo local (autenticação para Apple.com) e ele falhou porque o Fiddler não foi capaz de passar este certificado adiante.
Tente desativar o Fiddler para verificar e, se essa for a solução, você provavelmente precisará instalar o certificado em sua máquina ou de alguma forma que o Fiddler possa usá-lo.
fonte
O código abaixo resolveu meu problema:
fonte