Błąd WCF „Może to być spowodowane faktem, że certyfikat serwera nie jest poprawnie skonfigurowany z HTTP.SYS w przypadku HTTPS”

80

Mam problem z używaniem wywołania WCF z usługi systemu Windows do mojej usługi WCF działającej na moim serwerze sieci Web. To wezwanie działało przez kilka tygodni, ale nagle przestało działać i od tamtej pory nie działa.

Wyjątek, który otrzymuję, to:

Wystąpił błąd ogólny System.ServiceModel.CommunicationException: Wystąpił błąd podczas wysyłania żądania HTTP

a potem mówi

Może to być spowodowane faktem, że certyfikat serwera nie jest poprawnie skonfigurowany z HTTP.SYS w przypadku HTTPS. Może to być również spowodowane niezgodnością powiązania zabezpieczeń między klientem a serwerem.

Zabezpieczenia, których używam na obu końcach, to wsHttpBinding, bez żadnego szyfrowania. Używa też tylko protokołu HTTP, a nie HTTPS, więc nie jestem pewien, dlaczego narzeka na HTTPS.

Reszta wewnętrznego stosu wyjątków to:

SystemNet.WebException: połączenie podstawowe zostało zamknięte: wystąpił nieoczekiwany błąd podczas wysyłania. ---> System.IO.IOException: nie można zapisać danych w połączeniu transportowym: podano nieprawidłowy argument. ---> System.Net.Sockets.SocketException: podano nieprawidłowy argument w System.Net.Sockets.Socket.MultipleSend (bufory BufferOffsetSize [], SocketFlags socketFlags) w System.Net.Sockets.NetworkStream.MultipleWrite (BufferOffsetSize [] bufory)

Powinienem również zauważyć, że punkt w moim programie, w którym to się dzieje, znajduje się w wierszu „Execute” wywołania usługi sieciowej - to znaczy zaraz po wywołaniu usługi sieciowej i przekazaniu jej opakowanego obiektu DataContract, wysadza.

Wszystko, co robi ta usługa, to przekazywanie dużej ilości XML (przekazywanej jako obiekt .NET do wywołania po stronie klienta), z którym następnie wykonuje jakąś pracę. Prawdopodobnie przesyłanych jest około 100-200 tys. Plików XML. Podniosłem limity rozmiarów danych na obu końcach do ponad 6 megabajtów, ale to nie pomogło.

Jakieś pomysły?


Więcej informacji na ten temat:

Kiedy lokalnie powielamy środowisko klienta, okazuje się, że nie możemy przesłać dużych ilości XML, chyba że dokonamy następujących zmian: 1. Na serwerze ustaw "maxRequestLength" na 100 MB (dużo więcej niż wysyłamy) 2. Włącz klienta, ustawiliśmy wartość maxItemsInObjectGraph pod tagiem dataContractSerializer na „2147483646”.

Dzięki tym zmianom nasza lokalna instalacja zostanie pomyślnie przesłana. Jednak instalacja klienta na serwerze nadal kończy się niepowodzeniem. Co ciekawe, gdy zmieniliśmy wartość maxRequestLength na serwerze, nasza instalacja testowa zaczęła generować błąd związany z ustawieniem maxItemsInObjectGraph. Podczas gdy na serwerze naszego klienta nadal występuje pierwotny błąd „HTTP.sys”.

Jak zauważyłem wcześniej, w ogóle nie używamy SSL, a istnieją 2 inne wywołania usług internetowych, które wykonują i przesyłają XML w ten sam sposób. Jednak ponieważ niedziałające wywołanie serwisowe przesyła więcej danych, wydaje się, że jest to problem z rozmiarem.

Jeśli jednak problem, który ma klient, był taki sam, jak nasza instalacja testowa, nie rozumiem, dlaczego komunikat o błędzie klienta nie miałby być powiązany z błędem ObjectGraph.

Czy to możliwe, że po prostu otrzymujemy ogólny błąd „nieprawidłowy parametr” „HTTP.sys” dla każdego możliwego błędu na kliencie (tj. Tak naprawdę pojawia się również błąd objectGraph, ale po prostu go nie wyświetla?)

Sam Schutte
źródło
Mówisz, że przestał działać, czy zmienił się kod lub konfiguracja, która mogła być za to odpowiedzialna? czy możesz wysłać kod dla metody, którą wywołujesz, z przekazywanymi typami danych?
Tanner
Odkopię to i opublikuję. Myślę, że w zasadzie przekazuję tablicę obiektów „AppointmentData”, które są zdefiniowane w danych DataContract. Na pewno skomplikowane obiekty, więc sprawdzę twój post. Dzięki!
Sam Schutte,
Aha, i żaden kod ani konfiguracja nie zostały zmienione - działało dobrze przez tygodnie, a potem po prostu się zatrzymało. Możliwe, że ustawienia zapory klienta również zostały zmienione, ale dziwne jest to, że usługa, która wykonuje wywołanie WCF, może wywołać 2 inne metody usługi WCF, a także ma możliwość wysłania mi wiadomości e-mail z zawartością wyjątku ... na 2 z 3 wywołań WCF, ale nie ostatnie.
Sam Schutte,
2
Zawsze obawiam się „błędów ogólnych”, które sugerują możliwość, ponieważ tak naprawdę nie wiesz, czy sugestia dotyczy czerwonego śledzia, czy nie. Czy możesz przetestować, ustawiając security = none? Jeśli zgłoszenie serwisowe działa, oznacza to, że problem dotyczy certyfikatu (lub przynajmniej bezpieczeństwa). Chciałbym również zobaczyć konfigurację po obu stronach.
Mike L
Muszę to sprawdzić, ale jestem prawie pewien, że zabezpieczenia są już ustawione na brak ...
Sam Schutte

Odpowiedzi:

73

Mieliśmy ten problem, ponieważ serwer hosta został zaktualizowany do korzystania z protokołu TLS V1.2, a my łączyliśmy się przy użyciu standardowego protokołu SSL. To była aktualizacja dokonana w ramach testów piórkowych stron. Widzieliśmy problem w połączeniu kodu, ale nie przeglądarki przechodzące do wsdl. Poniższy kod rozwiązany:

if (System.Net.ServicePointManager.SecurityProtocol == (SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls))
    System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Zaczerpnięte stąd: Jak wyłączyć rezerwę SSL i używać tylko TLS dla połączeń wychodzących w .NET? (Łagodzenie skutków Pudla)

user369142
źródło
Dziękuję Ci! To mi pomogło. Musiałem to ustawić, jeśli wywołując C # DLL, wykonując wywołanie SOAP z aplikacji C ++. Jeśli ta sama biblioteka DLL języka C # została wywołana z aplikacji C #, nie było to potrzebne.
piksel
w moim przypadku: a) musiałem dodać using System.Netdo mojego pliku. b) wartość SecurityProtocol to „Default”. Zdecydowałem się usunąć „if” i przypisać SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 bez uprzedniego pytania. HTH, Marcelo
Marcelo Finki
1
2020. To samo rozwiązanie.
Anton Krouglov
28

Miałem ten sam problem z usługą działającą w IIS 7, usługa łączy się z serwerami wielu dostawców (niektóre SSL, niektóre nie) podczas dodawania nowego z nich (tym nowym dostawcą był TLS 1.2). Otrzymałem błąd po kilku żądaniach wykonane na oryginalnych serwerach (SSL).

Aby to potwierdzić, po prostu zapisałem System.Net.ServicePointManager.SecurityProtocolprzed każdym żądaniem do każdego dostawcy.

Niski i po ponownym uruchomieniu usługi (lub ponownym uruchomieniu puli aplikacji) otrzymywałem dane wyjściowe, Ssl3, Tlsale po kilku żądaniach do oryginalnych serwerów dostawcy zmieniło się to na Ssl3i żądania do usługi TLS spowodowały błąd.

Aby to naprawić, po prostu zrobiłem to, co zasugerował user369142. Przed każdym żądaniem do nowego serwera:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;

i żadnych więcej błędów.

Selwin Dedekind
źródło
Aby korzystać z TLS 1.2+, musisz mieć co najmniej .NET 4.5+. Źródło: blogs.perficient.com/microsoft/2016/04/tsl-1-2-and-net-support
xx1xx
Dziękuję bardzo, czy zamiast tego można by go użyć z liczbami całkowitymi do wyliczenia: System.Net.ServicePointManager.SecurityProtocol = 123 => enum1 | enum2 itd. Dla innych frameworków?
MirlvsMaximvs
Nie musisz ustawiać tego przed każdym żądaniem - wystarczy ustawić je raz w zdarzeniu początkowym aplikacji - jest to statyczna właściwość, którą ustawiasz.
user369142
9

Miał ten problem z prawdziwym powiązaniem HTTPS i tym samym wyjątkiem z „Może to wynikać z faktu, że certyfikat serwera nie jest poprawnie skonfigurowany z HTTP.SYS w przypadku HTTPS ...”. Po podwójnym sprawdzeniu wszystkiego w kodzie i konfiguracji, wydaje się, że komunikat o błędzie nie jest tak mylący jak wewnętrzne wyjątki, więc po szybkim sprawdzeniu okazało się, że port 443 został przechwycony przez skype (na serwerze deweloperskim). Radzę przyjrzeć się temu, co wstrzymuje żądanie (Fiddler może tu pomóc) i upewnić się, że możesz dotrzeć do frontu usługi (wyświetl plik .svc w przeglądarce) i jego metadane.

Powodzenia.

nsides
źródło
9

W moim przypadku musiałem włączyć SchUseStrongCrypto.Net To zmusza serwer do nawiązywania połączenia przy użyciu TLS 1.0, 1.1 lub 1.2. Bez SchUseStrongCryptowłączonej opcji połączenie próbowało używać protokołu SSL 3.0, który został wyłączony na moim zdalnym punkcie końcowym.

Klucze rejestru umożliwiające korzystanie z silnego krypto:

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
ElektryczneNozyce
źródło
6

Dla nas ten błąd był spowodowany tym, że komputer dewelopera, na którym działa usługa, miał skonfigurowane usługi IIS do wiązania portu 443 tylko z portem 127.0.0.1.

W Menedżerze usług IIS kliknij witrynę internetową prawym przyciskiem myszy i wybierz polecenie Edytuj powiązania. Jeśli wpis dotyczący portu 443ma adres IP 127.0.0.1, zmień go na *.

Joe Daley
źródło
5

Po wielu poszukiwaniach i daremnych poszukiwaniach, w końcu je otrzymałem. Zainstalowałem TLS 1.2 na serwerze, na którym działa moja usługa wcf Mój klient został skonfigurowany poprawnie, ale został zbudowany na .NET 4.5.1, podczas gdy wcf działał na platformie .NET 4.6.1. Zarówno klient, jak i serwer muszą mieć tę samą wersję .NET, jeśli używasz protokołu TLS 1.2. Mam nadzieję, że kiedyś komuś to pomoże :-)

Sotiris Zegiannis
źródło
2
Musiałby to być błąd, gdyby tak było, protokół nie powinien różnić się w zależności od wersji .NET, nie wspominając o usługach lub klientach, które nawet nie używają .NET.
Joel McBeth
Ta wskazówka rozwiązała mój problem. Miałem projekt WPF z odniesieniem do innego projektu B. Projekt B to 4.5.2, a projekt WPF to 4.6.1. Wykonanie obu wersji 4.5.2 rozwiązało problem.
Ignacio Hagopian
5

Zmień aplikację kliencką na 4.5 lub nowszą. JEŚLI masz 4,5 lat, użyj: System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12 / Tls1.1 / Tls1.0 według potrzeb lub możesz zaktualizować aplikację do wersji 4.6.1.

Shashank
źródło
4

Prawie ten sam problem wystąpił ostatnio i okazało się, że jest on spowodowany przez aktualizację KB980436 firmy Microsoft ( http://support.microsoft.com/KB/980436 ) instalowaną na komputerze wywołującym. Rozwiązaniem dla nas, poza zwykłym odinstalowaniem, było wykonanie instrukcji z witryny KB, aby ustawić wartość DWORD UseScsvForTls w rejestrze na 1. Jeśli zauważysz, że ta aktualizacja jest zainstalowana w systemie wywołującym, możesz spróbować .

atlas944
źródło
Czy Twoje połączenia korzystały z protokołu HTTPS? A może były niezaszyfrowane jako OP?
roufamatic
3

Miałem ten problem podczas uruchamiania starszych skrzynek XP SP3 z usługami IIS i Glassfish na Amazon AWS. Amazon zmienił swoje domyślne ustawienia modułu równoważenia obciążenia, aby NIE włączyć szyfrowania DES-CBC3-SHA. Musisz to włączyć na amazon ELB, jeśli chcesz, aby starszy XP TLS 1.0 działał przeciwko ELB dla HTTPS, w przeciwnym razie pojawi się ten błąd. Szyfry można zmienić w ELB, przechodząc do zakładki słuchacza w konsoli i klikając szyfr obok konkretnego słuchacza, którego próbujesz uruchomić.

Fred Covely
źródło
2

Jeśli usługa WCF korzysta z platformy .NET Framework 4.0 i ktoś wyłączył protokół TLS 1.0 na serwerze, zobaczysz ten wyjątek. Ponieważ .net 4.0 nie obsługuje wyższych wersji TLS.

Obsługiwane protokoły: https://msdn.microsoft.com/en-us/library/system.security.authentication.sslprotocols(v=vs.100).aspx

user1069816
źródło
4
Właściwie istnieje obejście, którego nadal możesz używać: ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; //TLS 1.2i będzie działać w NET 4.0.
F34R
@ F34R Twój komentarz rozwiązał mój problem z aplikacją .NET 4.0 próbującą wysłać żądanie SOAP do punktu końcowego, który został niedawno przekonwertowany z http na https. Obsługiwane przez blogs.perficient.com/microsoft/2016/04/tsl-1-2-and-net-support
Wesley Musgrove
1

Widziałem te szczególne wyjątki związane ze złożonymi problemami typu DataType, zobacz następujący post, jeśli przekazujesz kolekcje lub wyliczenia:

Złożone typy danych

Garbarz
źródło
Przyjrzeliśmy się problemowi z typem danych - po prostu wysyłamy zwykłe stare obiekty .NET, które są zdefiniowane w naszym dataContract - żadnych elementów wyliczalnych ani podobnych rzeczy. Zainstalowaliśmy jednak niektóre narzędzia do śledzenia debugowania wspomniane w tym artykule i mogliśmy zobaczyć nasze 2 działające wywołania, ale nic nie pojawiło się w trzecim wywołaniu „niedziałającym”. Wskazuje mi to, że w ogóle nie schodzi z komputera klienta.
Sam Schutte,
4
@SamSchutte: czy ten błąd został kiedykolwiek rozwiązany? Czy mógłbyś podać, jakie było rozwiązanie?
VoodooChild
1

Jeśli używasz trybu transferu = przesyłany strumieniowo, spróbuj zmienić go na buforowany.

Jeśli to nie jest problem, możesz wysłać swoją konfigurację.

Shiraz Bhaiji
źródło
1

Ponieważ przez wiele tygodni wszystko działało dobrze, a potem przestało, wątpię, by miało to coś wspólnego z twoim kodem. Być może błąd występuje, gdy usługa jest aktywowana w usługach IIS / ASP.NET, a nie podczas wywoływania kodu. Środowisko wykonawcze może po prostu sprawdzać konfigurację witryny internetowej i generować ogólny komunikat o błędzie, który nie ma nic wspólnego z usługą.

Podejrzewam, że certyfikat wygasł lub powiązania są skonfigurowane nieprawidłowo. Jeśli witryna internetowa jest nieprawidłowo skonfigurowana pod kątem protokołu HTTPS, niezależnie od tego, czy w Twoim kodzie są one używane, czy nie, możesz otrzymać ten błąd.

Jakub
źródło
1

Spróbuj przeglądać usługę w przeglądarce iw trybie Https, jeśli nie jest to przeglądarka internetowa, to udowodni przyczynę tego błędu. Teraz, aby rozwiązać ten błąd, musisz sprawdzić:

  • port https, sprawdź, czy nie jest używany przez inne zasoby (witryna)
  • Sprawdź, czy certyfikat dla https jest poprawnie skonfigurowany, czy nie (sprawdź urząd podpisu, certyfikat z podpisem własnym, użycie wielu certyfikatów)
  • Sprawdź powiązanie usługi WCF i konfigurację dla trybu HTTPS
Ankur Bhutani
źródło
1

Nasz problem polegał na tym, że numer portu w punkcie końcowym był nieprawidłowo ustawiony na 8080. Zmieniono go na 8443 i zadziałało.

tntice
źródło
1

Zamiast jawnie ustawiać protokół zabezpieczeń, lepszym sposobem jest ustawienie pliku web.config <compilation targetFramework = "4.5"> lub nowszego.

Vijay Jagdale
źródło
1

Rozwiązałem problem, aktualizując moją wersję .NetFramework z 4.5.2 do 4.7.2.

Mohammad
źródło
0

Niedawno tego doświadczyłem:

System.ServiceModel.CommunicationException:

Wystąpił błąd podczas wysyłania żądania HTTP do http://example.com/WebServices/SomeService.svc . Może to być spowodowane faktem, że certyfikat serwera nie jest poprawnie skonfigurowany z HTTP.SYS w przypadku HTTPS. Może to być również spowodowane niezgodnością powiązania zabezpieczeń między klientem a serwerem.

---> System.Net.WebException: połączenie podstawowe zostało zamknięte: wystąpił nieoczekiwany błąd podczas wysyłania.

---> System.IO.IOException: nie można zapisać danych w połączeniu transportowym: istniejące połączenie zostało wymuszone przez hosta zdalnego.

Dowiedziałem się od administratora, że ​​pula aplikacji IIS, na której była hostowana usługa sieciowa, została automatycznie przywrócona po wyczerpaniu pamięci. Błąd na kliencie wystąpił podczas odtwarzania puli aplikacji.

Zwiększenie pamięci dostępnej dla puli aplikacji rozwiązało natychmiastowy problem.

Daniel Ballinger
źródło
0

Nasze aplikacje zostały niedawno wymuszone z SSL na TLS przez aktualizację systemu operacyjnego urządzenia sieciowego (F5). Naprawiliśmy ten błąd, ponownie generując certyfikaty z podpisem własnym. Mam nadzieję, że pomoże to komuś w przyszłości rozwiązać ten problem, ponieważ przed znalezieniem rozwiązania spędziliśmy wiele czasu na rozwiązywanie problemów z oknami obsługi.

mjw
źródło
0

Niedawno tego doświadczyłem:

System.ServiceModel.CommunicationException:

Wystąpił błąd podczas wysyłania żądania HTTP do http://example.com/WebServices/SomeService.svc . Może to wynikać z faktu, że certyfikat serwera nie jest poprawnie skonfigurowany z HTTP.SYS w przypadku HTTPS. Może to być również spowodowane niezgodnością powiązania zabezpieczeń między klientem a serwerem.

---> System.Net.WebException: połączenie podstawowe zostało zamknięte: wystąpił nieoczekiwany błąd podczas wysyłania.

---> System.IO.IOException: nie można zapisać danych w połączeniu transportowym: istniejące połączenie zostało wymuszone przez hosta zdalnego.

Nasza licencja na proxy bluecoat wygasła! więc nie można było nawiązać połączenia ze stroną zewnętrzną (internet).

Kret
źródło
0

Mieliśmy ten sam problem iw naszym przypadku został on rozwiązany przez ponowną instalację certyfikatu i ponowne utworzenie powiązania. Doprowadziło nas do tego, że nawet pobranie prostego pliku obrazu png na stronie daje ten sam błąd.

MiguelSlv
źródło