Ошибка WCF «Это может быть связано с тем, что сертификат сервера неправильно настроен с HTTP.SYS в случае HTTPS»

80

У меня проблема с использованием вызова WCF из службы Windows в мою службу WCF, работающую на моем веб-сервере. Этот вызов работал несколько недель, но затем внезапно перестал работать и с тех пор не работал.

Я получаю исключение:

Произошла общая ошибка System.ServiceModel.CommunicationException: произошла ошибка при выполнении HTTP-запроса

а затем он говорит

Это может быть связано с тем, что сертификат сервера неправильно настроен с HTTP.SYS в случае HTTPS. Это также может быть вызвано несоответствием привязки безопасности между клиентом и сервером.

Безопасность, которую я использую на обоих концах, - wsHttpBinding без какого-либо шифрования. Он также просто использует HTTP, а не HTTPS, поэтому я не уверен, почему он жалуется на HTTPS.

Остальная часть внутреннего стека исключений:

SystemNet.WebException: базовое соединение было закрыто: при отправке произошла непредвиденная ошибка. ---> System.IO.IOException: невозможно записать данные в транспортное соединение: предоставлен недопустимый аргумент. ---> System.Net.Sockets.SocketException: недопустимый аргумент был указан в System.Net.Sockets.Socket.MultipleSend (BufferOffsetSize [] буферы, SocketFlags socketFlags) в System.Net.Sockets.NetworkStream.MultipleWrite (BufferOffsetSize [] буферы)

Я также должен отметить, что точка в моей программе, где это происходит, находится в строке «Execute» вызова веб-службы, то есть сразу после того, как я вызываю веб-службу и передаю ей завернутый объект DataContract, он взрывается.

Все, что делает эта служба, - это передача большого количества XML (переданного как объект .NET вызову на стороне клиента), с которым она затем выполняет некоторую работу. Вероятно, передается около 100-200k XML. Я увеличил пределы размеров данных на обоих концах до более 6 мегабайт, но это не помогло.

Есть идеи?


Дополнительная информация по этому вопросу:

Когда мы дублируем клиентскую среду локально, мы обнаруживаем, что не можем загружать большие объемы XML, если не внесем следующие изменения: 1. На сервере установите для параметра «maxRequestLength» значение 100 МБ (намного больше, чем мы отправляем) 2. Вкл. клиент, мы устанавливаем значение maxItemsInObjectGraph в теге dataContractSerializer равным «2147483646».

С этими изменениями наша локальная установка успешно загружается. Однако установка клиента на их сервер по-прежнему не выполняется. Интересно отметить, что как только мы изменили значение maxRequestLength на сервере, наша тестовая установка начала выдавать ошибку, конкретно связанную с параметром maxItemsInObjectGraph. В то время как на сервере нашего клиента по-прежнему происходит исходная ошибка «HTTP.sys».

Как я уже отмечал ранее, мы вообще не используем SSL, и есть 2 других вызова веб-сервисов, которые выполняют и загружают XML таким же образом. Однако, поскольку вызов неработающей службы передает больше данных, это, по-видимому, проблема размера.

Однако, если проблема, с которой столкнулся клиент, была такой же, как и при нашей тестовой установке, я не понимаю, почему сообщение об ошибке клиента не связано с ошибкой ObjectGraph.

Возможно ли, что мы просто получаем общую ошибку «недопустимый параметр» «HTTP.sys» для каждой возможной ошибки на клиенте (т. Е. Он действительно получает ошибку objectGraph, но просто не показывает ее?)

Сэм Шютте
источник
Вы говорите, что он перестал работать, изменился ли какой-либо код или конфигурация, которые могли быть причиной этого? Можете ли вы опубликовать код для метода, который вы вызываете, с типами данных, которые передаются?
Tanner
Я выкопаю это и выложу. Я думаю, что в основном передаю массив объектов «AppointmentData», которые определены в материале DataContract. Конечно, сложные объекты, так что я проверю ваш пост. Благодаря!
Сэм Шютте,
Да, еще ни код, ни конфигурация не менялись - неделями работали нормально, а потом просто перестали. Возможно, настройки брандмауэра клиента тоже были изменены, но что странно, так это то, что служба, выполняющая вызов WCF, может вызывать 2 других метода службы WCF, а также имеет возможность отправить мне электронное письмо с содержимым исключения ... так что он получает вышел на 2 из 3 вызовов WCF, но не на последний.
Сэм Шютте,
2
Я всегда с подозрением отношусь к «Общим ошибкам», которые затем предполагают возможность, потому что вы действительно не знаете, является ли предложение отвлекающим фактором или нет. Можете ли вы протестировать, установив security = none? Если сервисный вызов работает, он сообщает нам, что сертификат (или, по крайней мере, безопасность) является проблемой. Также хотелось бы увидеть конфиг с обеих сторон.
Mike L
Придется проверить, но я почти уверен, что безопасность уже отключена ...
Сэм Шутте,

Ответы:

73

У нас возникла эта проблема, так как хост-сервер был обновлен для использования TLS V1.2, и мы подключались с использованием стандартного SSL. Это обновление было сделано в рамках тестирования сайтов на проникновение. Мы видели проблему в соединении кода, но не в браузерах, переходящих к wsdl. Ниже код решен:

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

Взято отсюда: Как отключить резервное копирование SSL и использовать только TLS для исходящих подключений в .NET? (Смягчение пуделей)

user369142
источник
Спасибо! Это мне помогло. Я должен был установить это, если вызов C # DLL делает вызов SOAP из приложения C ++. Если та же библиотека C # вызывалась из приложения C #, в этом не было необходимости.
пиксель
в моем случае: а) мне нужно было добавить using System.Netв свой файл. б) значение SecurityProtocol было «По умолчанию». Я решил убрать «если» и назначить SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 без предварительного запроса. HTH, Марсело
Марсело Финки
1
2020. То же решение.
Антон Круглов
28

У меня была такая же проблема со службой, работающей на IIS 7, служба подключается к серверам нескольких поставщиков (некоторые SSL некоторые нет) при добавлении нового из них (этим новым поставщиком был TLS 1.2). Я бы получил сообщение об ошибке после того, как несколько запросов были сделано на исходных серверах (SSL).

Чтобы подтвердить это, я просто регистрировал System.Net.ServicePointManager.SecurityProtocolкаждый запрос перед каждым поставщиком.

Низкий и смотрите, после перезапуска службы (или перезапуска пула приложений) я бы получил результат, Ssl3, Tlsно после нескольких запросов к исходным серверам поставщика это изменилось, Ssl3и запросы к службе TLS дали ошибку.

Чтобы исправить, я просто сделал то, что предложил user369142. Перед каждым запросом к новому серверу:

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

и больше никаких ошибок.

Селвин Дедекинд
источник
Для использования TLS 1.2+ вам потребуется как минимум .NET 4.5+. Источник: blogs.perficient.com/microsoft/2016/04/tsl-1-2-and-net-support
xx1xx,
Большое спасибо, можно ли вместо этого использовать его с целыми числами для перечисления: System.Net.ServicePointManager.SecurityProtocol = 123 => enum1 | enum2 и т. Д. Для других фреймворков?
MirlvsMaximvs 05
Вам не нужно устанавливать это перед каждым запросом - просто установите его один раз в событии запуска приложения - это статическое свойство, которое вы устанавливаете.
user369142
9

Была ли эта проблема с истинной привязкой HTTPS и такое же исключение с «Это могло быть из-за того, что сертификат сервера неправильно настроен с HTTP.SYS в случае HTTPS ...». После двойной проверки всего кода и конфигурации кажется, что сообщение об ошибке не так вводит в заблуждение, как внутренние исключения, поэтому после быстрой проверки мы обнаружили, что порт 443 был перехвачен скайпом (на сервере разработки). Я рекомендую вам взглянуть на то, что задерживает запрос (здесь может помочь Fiddler), и убедитесь, что вы можете добраться до службы (просмотрите .svc в своем браузере) и ее метаданных.

Удачи.

нсайд
источник
9

В моем случае мне пришлось включить SchUseStrongCrypto.Net. Это заставляет сервер устанавливать соединение с использованием TLS 1.0, 1.1 или 1.2. БезSchUseStrongCrypto включения соединение пыталось использовать SSL 3.0, который был отключен на моей удаленной конечной точке.

Ключи реестра, позволяющие использовать сильное шифрование:

[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
источник
6

Для нас эта ошибка возникла из-за того, что на компьютере разработчика, на котором запущена служба, был настроен IIS для привязки порта 443 только к 127.0.0.1.

В диспетчере IIS щелкните правой кнопкой мыши веб-сайт и выберите «Изменить привязки». Если запись для порта 443имеет IP-адрес 127.0.0.1, измените его на *.

Джо Дейли
источник
5

После долгих поисков и тщетного взятия имени лорда я наконец получил его. Я установил TLS 1.2 на сервере, на котором работает моя служба wcf. Мой клиент был настроен правильно, но он был построен на .NET 4.5.1, тогда как wcf был на .NET 4.6.1. И клиент, и сервер должны иметь одну и ту же версию .NET, если вы используете TLS 1.2. Надеюсь, когда-нибудь это кому-нибудь поможет :-)

Сотирис Зегианнис
источник
2
Это должно было быть ошибкой, если бы это было так, протокол не должен различаться в зависимости от версии .NET, не говоря уже о службах или клиентах, которые даже не используют .NET.
Джоэл Макбет,
Эта подсказка решила мою проблему. У меня был проект WPF со ссылкой на другой проект B. Проект B был 4.5.2, а проект WPF - 4.6.1. Создание обоих версий 4.5.2 решило проблему.
Игнасио Акопян
5

Измените клиентское приложение на 4.5 и выше. ЕСЛИ у вас 4.5, тогда используйте: System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12 / Tls1.1 / Tls1.0 по мере необходимости, или вы можете обновить свое приложение до версии выше 4.6.1.

Шашанк
источник
4

У нас недавно возникла почти такая же проблема, и она оказалась вызвана обновлением Microsoft KB980436 ( http://support.microsoft.com/KB/980436 ), установленным на вызывающем компьютере. Исправление для нас, кроме его полного удаления, заключалось в том, чтобы следовать инструкциям на сайте KB для установки параметра UseScsvForTls DWORD в реестре на 1. Если вы видите, что это обновление установлено в вашей вызывающей системе, вы можете попробовать его. .

atlas944
источник
Были ли ваши звонки с использованием HTTPS? Или они были незашифрованными как OP?
roufamatic
3

У меня возникла эта проблема при запуске старых пакетов XP SP3 против IIS и Glassfish на Amazon AWS. Amazon изменил настройки балансировщика нагрузки по умолчанию, чтобы НЕ включать шифр DES-CBC3-SHA. Вы должны включить это на amazon ELB, если хотите, чтобы старый XP TLS 1.0 работал с ELB для HTTPS, иначе вы получите эту ошибку. Шифры можно изменить в ELB, перейдя на вкладку слушателя в консоли и щелкнув шифр рядом с конкретным слушателем, который вы пытаетесь заставить работать.

Фред Ковли
источник
2

Если ваша служба WCF использует .NET framework 4.0 и кто-то отключил TLS 1.0 на сервере, вы увидите это исключение. Поскольку .net 4.0 не поддерживает более высокие версии TLS.

Поддерживаемые протоколы: https://msdn.microsoft.com/en-us/library/system.security.authentication.sslprotocols(v=vs.100).aspx

user1069816
источник
4
На самом деле есть обходной путь, вы все еще можете использовать: ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; //TLS 1.2и он будет работать в NET 4.0.
F34R 07
@ F34R ваш комментарий решил мою проблему для приложения .NET 4.0, пытающегося сделать запрос SOAP к конечной точке, которая недавно была преобразована с http на https. При поддержке blogs.perficient.com/microsoft/2016/04/tsl-1-2-and-net-support
Уэсли Масгроув,
1

Я видел эти конкретные исключения, связанные с проблемами сложного типа данных, см. Следующий пост, если вы передаете коллекции или перечисления:

Сложные типы данных

Таннер
источник
Мы рассмотрели проблему с типом данных - мы просто отправляем простые старые объекты .NET, которые определены в нашем dataContract - никаких перечисляемых объектов и тому подобного. Мы установили некоторые инструменты отслеживания отладки, упомянутые в этой статье, и могли видеть, как проходят наши 2 рабочих вызова, но для третьего «неработающего» вызова ничего не появилось. Это указывает мне на то, что он даже не выходит из клиентской машины.
Сэм Шутте,
4
@SamSchutte: устранялась ли эта ошибка? Не могли бы вы предоставить решение?
VoodooChild
1

Если вы используете режим передачи = поток, попробуйте изменить его на буферизованный.

Если проблема не в этом, не могли бы вы опубликовать свою конфигурацию.

Шираз Бхайджи
источник
1

Поскольку все работало нормально в течение нескольких недель, а затем остановилось, я сомневаюсь, что это как-то связано с вашим кодом. Возможно, ошибка возникает при активации службы в IIS / ASP.NET, а не при вызове вашего кода. Среда выполнения может просто проверять конфигурацию веб-сайта и выдавать общее сообщение об ошибке, не имеющее ничего общего с сервисом.

Подозреваю, что срок действия сертификата истек или привязки настроены неправильно. Если веб-сайт неправильно настроен для HTTPS, независимо от того, использует ли ваш код их или нет, вы можете получить эту ошибку.

Джейкоб
источник
1

Попробуйте просмотреть сервис в браузере и в режиме HTTPS, если он не доступен для просмотра, то это доказывает причину этой ошибки. Теперь, чтобы решить эту ошибку, вам нужно проверить:

  • https порт, проверьте, не используется ли он другими ресурсами (сайтом)
  • Проверьте, правильно ли настроен сертификат для https (проверьте центр подписи, самоподписанный сертификат, использование нескольких сертификатов)
  • проверьте привязку и конфигурацию службы WCF для режима Https
Анкур Бутани
источник
1

Наша проблема заключалась в том, что номер порта на конечной точке был неправильно установлен на 8080. Изменил его на 8443, и это сработало.

tntice
источник
1

Вместо того, чтобы явно устанавливать протокол безопасности, лучше установить web.config <compilation targetFramework = "4.5"> или выше.

Виджей Джагдейл
источник
1

Я решил свою проблему, обновив мою версию .NetFramework с 4.5.2 до 4.7.2.

Мохаммад
источник
0

Совсем недавно испытал такое:

System.ServiceModel.CommunicationException:

Ошибка при выполнении HTTP-запроса к http://example.com/WebServices/SomeService.svc . Это может быть связано с тем, что сертификат сервера неправильно настроен с HTTP.SYS в случае HTTPS. Это также может быть вызвано несоответствием привязки безопасности между клиентом и сервером.

---> System.Net.WebException: базовое соединение было закрыто: при отправке произошла непредвиденная ошибка.

---> System.IO.IOException: невозможно записать данные в транспортное соединение: существующее соединение было принудительно закрыто удаленным хостом.

Я узнал от администратора, что пул приложений IIS, в котором размещалась веб-служба, автоматически перезагружается после нехватки памяти. Ошибка на клиенте произошла при перезапуске пула приложений.

Увеличение объема памяти, доступной для пула приложений, сразу решило проблему.

Дэниел Баллинджер
источник
0

Наши приложения недавно были принудительно отключены от SSL к TLS через обновление ОС сетевого устройства (F5). Мы исправили эту ошибку, повторно сгенерировав самоподписанные сертификаты. Надеюсь, это поможет кому-то в будущем решить проблему, поскольку мы потратили несколько окон обслуживания на устранение неполадок, прежде чем прийти к решению.

mjw
источник
0

Совсем недавно испытал такое:

System.ServiceModel.CommunicationException:

Ошибка при выполнении HTTP-запроса к http://example.com/WebServices/SomeService.svc . Это могло быть связано с тем, что сертификат сервера неправильно настроен с HTTP.SYS в случае HTTPS. Это также может быть вызвано несоответствием привязки безопасности между клиентом и сервером.

---> System.Net.WebException: базовое соединение было закрыто: при отправке произошла непредвиденная ошибка.

---> System.IO.IOException: невозможно записать данные в транспортное соединение: существующее соединение было принудительно закрыто удаленным хостом.

Срок действия нашей лицензии прокси-сервера bluecoat истек! поэтому было невозможно связаться с внешней стороной (Интернет).

Моль
источник
0

У нас была такая же проблема, и в нашем случае она была решена путем переустановки сертификата и повторного создания привязки. Что привело нас к этому, так это то, что даже получение простого файла изображения png на сайте дает ту же ошибку.

MiguelSlv
источник