Problem: w moich dziennikach pojawia się ten wyjątek „PODSTAWOWE POŁĄCZENIE ZOSTAŁO ZAMKNIĘTE: NIEOCZEKIWANY BŁĄD PRZY WYSYŁANIU” i powoduje to zerwanie naszej integracji OEM z naszym systemem marketingu e-mailowego w losowych odstępach czasu od [1–4 godziny]
Moja witryna jest hostowana na serwerze Windows 2008 R2 z usługami IIS 7.5.7600. Ta witryna zawiera dużą liczbę komponentów OEM i obszerny pulpit nawigacyjny. Wszystko działa dobrze ze wszystkimi innymi elementami witryny, z wyjątkiem jednego z naszych komponentów e-mail marketingu, którego używamy jako rozwiązanie iframe na naszym pulpicie nawigacyjnym. Sposób działania jest taki, że wysyłam obiekt httpWebRequestobject ze wszystkimi poświadczeniami i otrzymuję adres URL z powrotem, który umieszczam w ramce iframe i działa. Ale to działa tylko przez jakiś czas [1 godzina - 4 godziny], a potem pojawia się poniższy wyjątek „PODSTAWOWE POŁĄCZENIE ZOSTAŁO ZAMKNIĘTE: NIEOCZEKIWANY BŁĄD WYSTĄPIŁ PRZY WYSYŁANIU” i nawet jeśli system próbuje uzyskać adres URL z httpWebRequest kończy się niepowodzeniem z tym samym wyjątkiem. Jedynym sposobem na przywrócenie jej działania jest ponowne wykorzystanie puli aplikacji lub edytowanie czegokolwiek w pliku web.config.
Opcja wypróbowana
Wyraźnie dodane, keep-alive = false
keep-alive = true
Wydłużono limit czasu: <httpRuntime maxRequestLength="2097151" executionTimeout="9999999" enable="true" requestValidationMode="2.0" />
Przesłałem tę stronę do witryny bez SSL, aby sprawdzić, czy certyfikat SSL na naszym serwerze produkcyjnym nawiązuje połączenie, aby w jakiś sposób zrzucić to.
Każdy kierunek w kierunku rozwiązania jest bardzo cenny.
Kod :
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`
źródło
Odpowiedzi:
Dla mnie był to tls12:
źródło
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
Jeśli utkniesz z .Net 4.0, a witryna docelowa korzysta z protokołu TLS 1.2, potrzebujesz zamiast tego następującego wiersza.
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
źródło: Obsługa TLS 1.2 i .NET: jak uniknąć błędów połączenia
źródło
(SecurityProtocolType)768
można go użyć dla „Tls11” (tj. TLS 1.1).Poniższy kod rozwiązał problem
źródło
ServicePointManager.SecurityProtocol
jest to obiekt statyczny, co oznacza, że zmiana tej wartości wpłynie na wszystkie sekwencje podrzędneWebRequest
lubWebClient
wywołania. Możesz utworzyć osobne,AppDomain
jeśli chceszServicePointManager
mieć inne ustawienia. Więcej szczegółów znajdziesz na stackoverflow.com/questions/3791629/… .Od kilku dni mam ten sam problem z integracją, która również „działała wcześniej”.
Po prostu spróbowałem z czystej depresji
To rozwiązało problem ... nawet jeśli integracja wykorzystuje wyłącznie SSLv3.
Uświadomiłem sobie, że coś jest nie tak, odkąd Fiddler poinformował, że istnieje „pusty szyfr negocjacyjny TLS” lub coś w tym stylu.
Mam nadzieję, że to działa!
źródło
W moim przypadku witryna, z którą się łączę, została zaktualizowana do TLS 1.2. W rezultacie musiałem zainstalować .net 4.5.2 na swoim serwerze WWW, aby go obsługiwać.
źródło
Przejdź do swojego web.config / App.config, aby sprawdzić, którego środowiska uruchomieniowego .net używasz
Oto rozwiązanie:
.NET 4.6 i nowsze. Nie musisz wykonywać żadnej dodatkowej pracy, aby obsługiwać protokół TLS 1.2, jest on domyślnie obsługiwany.
.NET 4.5. Obsługiwany jest protokół TLS 1.2, ale nie jest to protokół domyślny. Aby z niej korzystać, musisz wyrazić zgodę. Poniższy kod ustawi TLS 1.2 jako domyślny, upewnij się, że wykonałeś go przed nawiązaniem połączenia z zabezpieczonym zasobem:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
źródło
Odkryłem, że to znak, że serwer, na którym wdrażasz kod, ma zainstalowaną starą platformę .NET, która nie obsługuje TLS 1.1 ani TLS 1.2. Kroki do naprawienia:
Najnowszy pakiet deweloperski i środowisko wykonawcze .NET można pobrać z tego adresu URL: http://getdotnet.azurewebsites.net/target-dotnet-platforms.html
źródło
Wystąpił problem, w wyniku którego witryna, która uzyskiwała dostęp do naszego interfejsu API, otrzymywała komunikat „Połączenie podstawowe zostało zamknięte: podczas wysyłania wystąpił nieoczekiwany błąd”. wiadomość.
Ich kod był mieszanką .NET 3.x i 2.2, co, jak rozumiem, oznacza, że używają TLS 1.0.
Poniższa odpowiedź może pomóc w zdiagnozowaniu problemu, włączając protokoły TLS 1.0, SSL 2 i SSL3, ale dla jasności: nie chcesz tego robić na dłuższą metę, ponieważ wszystkie trzy z tych protokołów są uważane za niezabezpieczone i nie powinny być dłużej używany :
Aby nasze usługi IIS odpowiadały na ich wywołania API, musieliśmy dodać ustawienia rejestru na serwerze IIS, aby jawnie włączyć wersje TLS - UWAGA: Po wprowadzeniu tych zmian należy ponownie uruchomić serwer Windows (nie tylko usługę IIS):
Jeśli to nie wystarczy, możesz również poeksperymentować z dodaniem wpisu dla SSL 2.0:
Żeby było jasne, nie jest to przyjemne rozwiązanie , a właściwym rozwiązaniem jest skłonienie dzwoniącego do korzystania z TLS 1.2, ale powyższe może pomóc zdiagnozować, że to jest problem.
Możesz przyspieszyć dodawanie tych wpisów reg za pomocą tego skryptu PowerShell:
To zmodyfikowana wersja skryptu ze strony pomocy firmy Microsoft dotyczącej konfiguracji TLS dla VMM . Ten artykuł w basics.net był stroną, która pierwotnie podsunęła mi pomysł, aby przyjrzeć się tym ustawieniom.
źródło
Poprostu dodaj:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
źródło
Jeśli komuś pomogło, u nas był problem z brakującym certyfikatem. Środowisko to Windows Server 2016 Standard z .Net 4.6.
Istnieje identyfikator URI https usługi WCF hostowany samodzielnie, dla którego usługa Service.Open () byłaby wykonywana bez błędów. Inny wątek będzie miał dostęp do https: // OurIp: 443 / OurService? Wsdl, aby upewnić się, że usługa jest dostępna. Dostęp do WSDL, który się nie udał z:
Połączenie bazowe zostało zamknięte: podczas wysyłania wystąpił nieoczekiwany błąd.
Korzystanie z ServicePointManager.SecurityProtocol z odpowiednimi ustawieniami nie działa. Nie pomogła też zabawa z rolami i funkcjami serwera. Następnie wkroczył Jaise George , SE, rozwiązując problem w ciągu kilku minut. Jaise zainstalował certyfikat z podpisem własnym w usługach IIS, eliminując problem. Oto, co zrobił, aby rozwiązać ten problem:
(1) Otwórz menedżera IIS (inetmgr) (2) Kliknij węzeł serwera w lewym panelu i dwukrotnie kliknij „Certyfikaty serwera”. (3) Kliknij „Utwórz certyfikat z podpisem własnym” w prawym panelu i wpisz dowolną nazwę, aby uzyskać przyjazną nazwę. (4) Kliknij „Domyślna witryna internetowa” w lewym panelu, kliknij „Powiązania” w prawym panelu, kliknij „Dodaj”, wybierz „https”, wybierz właśnie utworzony certyfikat i kliknij „OK” (5) Dostęp adres URL https, powinien być dostępny.
źródło
Po prostu zmień wersję aplikacji, np. 4.0 na 4.6 i opublikuj ten kod.
Dodaj również poniższe linie kodu:
źródło
Użycie serwera proxy do debugowania HTTP może to spowodować - na przykład Fiddler.
Ładowałem certyfikat PFX z pliku lokalnego (uwierzytelnianie do Apple.com) i nie powiodło się, ponieważ Fiddler nie mógł przekazać tego certyfikatu dalej.
Spróbuj wyłączyć Fiddlera, aby sprawdzić, a jeśli to jest rozwiązanie, prawdopodobnie musisz zainstalować certyfikat na swoim komputerze lub w inny sposób, aby Fiddler mógł go używać.
źródło
Poniższy kod rozwiązał mój problem:
źródło