Вопрос

Итак, я добавил ServiceReference в консольное приложение C#, которое вызывает веб-службу, предоставляемую Oracle.

У меня все настроено, и все работает отлично, когда не используется SSL (http).Сейчас я пытаюсь настроить его с помощью SSL, и у меня возникают проблемы с добавлением его в ссылки на службы (или даже в веб-ссылки).Например, URL-адрес (https), по которому предоставляется служба, не возвращает соответствующие веб-методы, когда я пытаюсь добавить его в Visual Studio.

Базовое соединение было закрыто:При отправке произошла непредвиденная ошибка.Получен неожиданный EOF или 0 байт из транспортного потока.Метаданные содержат ссылку, которую невозможно разрешить:'https://srs204.mywebsite.ca:7776/SomeDirectory/MyWebService?WSDL'

Еще одна проблема, с которой я столкнулся, связана с управлением и развертыванием сертификатов.У меня есть около 1000 внешних клиентских сайтов, которым потребуется использовать эту небольшую утилиту, и им потребуется установить сертификат в соответствующем хранилище сертификатов, чтобы подключиться к веб-службе.Не уверен, что это лучший подход к решению этой проблемы.Должны ли они быть в корневом хранилище?

Я провел немало часов в Интернете, просматривая различные варианты, но нигде не смог получить четкого ответа.

Подводя итог, у меня есть пара вопросов:

1) У кого-нибудь есть хорошие ссылки по настройке веб-служб в Visual Studio, использующих SSL?

2) Как мне зарегистрировать сертификат?В каком магазине он должен быть?Могу ли я просто использовать что-то вроде CertMgr для его регистрации?

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

Это было полезно?

Решение

Ну, я это понял.Это заняло у меня гораздо больше времени, чем мне хотелось бы говорить, но я хотел поделиться своим решением, поскольку для меня ОГРОМНАЯ любимая мозоль - видеть стандарт.«О, я исправил это!Спасибо!" посты, которые заставляют всех задуматься о том, что же произошло на самом деле.

Так.

Основная проблема заключалась в том, что по умолчанию Visual Studio 2008 использует TLS для подтверждения SSL, а веб-служба на базе Oracle/Java, к которой я пытался подключиться, использовала SSL3.

Когда вы используете «Добавить ссылку на службу...» в Visual Studio 2008, у вас есть нет возможности указать, что протокол безопасности для менеджера точек обслуживания должен быть SSL3.

Пока не.

Вы берете статический документ WSDL и используйте wsdl.exe для создания прокси-класса.

wsdl /l:CS /protocol:SOAP /namespace:MyNamespace MyWebService.wsdl

Затем вы можете использовать Компилятор C Sharp чтобы превратить этот прокси-класс в библиотеку (.dll) и добавить его в свои проекты .Net «Ссылки».

csc /t:library /r:System.Web.Services.dll /r:System.Xml.dll MyWebService.cs

На этом этапе вам также необходимо убедиться, что вы также включили System.Web.Services в свои «Ссылки».

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

// We're using SSL here and not TLS. Without this line, nothing workie.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

Итак, я был очень впечатлен собой, поскольку тестирование на моем компьютере для разработчиков прошло отлично.Затем я выполнил развертывание на другом клиентском компьютере, и он не смог снова подключиться из-за проблемы с разрешениями/полномочиями.Для меня это пахло сертификатами (чем бы они ни пахли).Чтобы решить эту проблему, я использовал certmgr.exe зарегистрировать сертификат сайта в доверенном корне на локальном компьютере.

certmgr -add -c "c:\someDir\yourCert.cer" -s -r localMachine root

Это позволяет мне распространять сертификат на наши клиентские сайты и автоматически устанавливать его для пользователей.Я до сих пор не уверен, насколько «безопасными» будут разные версии Windows в отношении автоматической регистрации сертификатов, подобной этой, но пока это работает отлично.

Надеюсь, этот ответ поможет некоторым людям.Спасибо Blowdart за вашу помощь в этом вопросе и предоставление некоторой информации.

Другие советы

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

Предполагая, что вы крупная организация и внутри нее вы можете настроить собственный доверенный центр сертификации, это особенно легко сделать с помощью Активный каталог.Из этого центра сертификации сервер, на котором размещена служба Oracle, может запросить сертификат, и вы можете использовать политику AD, чтобы доверять корневому сертификату вашего внутреннего центра сертификации, поместив его в доверенный корень машинного хранилища.Это устранит необходимость вручную доверять или принимать сертификат в веб-службе.

Если клиентские машины являются внешними, вам придется попросить людей, предоставляющих услугу, либо приобрести «настоящий» сертификат у одного из известных центров сертификации, таких как Verisign, Thawte, GeoTrust и т. д.или в рамках установки упакуйте общедоступный сертификат и установите его в доверенные корневые центры сертификации на уровне компьютера на каждом компьютере.При этом возникают проблемы, например, невозможно отозвать сертификат, но запрос будет удален.

Спасибо за этот замечательный совет, быстро осмотрелся и обнаружил, что у вас появилось много хороших идей.Вот что я хочу добавить: я разбираюсь в webMethods, и (сюрприз!) у него те же проблемы, что и у сервера приложений Oracle, к которому вы подключились (SSL3 вместо TLS).Ваш подход отлично сработал, вот мое дополнение.

Учитывая статический класс «Фабрика», предоставьте эти два удобных элемента:

/// <summary>
/// Used when dispatching code from the Factory (for example, SSL3 calls)
/// </summary>
/// <param name="flag">Make this guy have values for debugging support</param>
public delegate void CodeDispatcher(ref string flag);

/// <summary>
/// Run code in SSL3 -- this is not thread safe. All connections executed while this
/// context is active are set with this flag. Need to research how to avoid this...
/// </summary>
/// <param name="flag">Debugging context on exception</param>
/// <param name="dispatcher">Dispatching code</param>
public static void DispatchInSsl3(ref string flag, CodeDispatcher dispatcher)
{
  var resetServicePoint = false;
  var origSecurityProtocol = System.Net.ServicePointManager.SecurityProtocol;
  try
  {
    System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3;
    resetServicePoint = true;
    dispatcher(ref flag);
  }
  finally
  {
    if (resetServicePoint)
    {
      try { System.Net.ServicePointManager.SecurityProtocol = origSecurityProtocol; }
      catch { }
    }
  }
}

А затем потреблять эту штуку (как вы уже наверняка догадались, но все равно сюда вставьте барабанную дробь):

    var readings = new ArchG2.Portal.wmArchG201_Svc_fireWmdReading.wmdReading[] {
      new ArchG2.Portal.wmArchG201_Svc_fireWmdReading.wmdReading() {
        attrID = 1, created = DateTime.Now.AddDays(-1), reading = 17.34, userID = 2
      },
      new ArchG2.Portal.wmArchG201_Svc_fireWmdReading.wmdReading() {
        attrID = 2, created = DateTime.Now.AddDays(-2), reading = 99.76, userID = 3
      },
      new ArchG2.Portal.wmArchG201_Svc_fireWmdReading.wmdReading() {
        attrID = 3, created = DateTime.Now.AddDays(-5), reading = 82.17, userID = 4
      }
    };
    ArchG2.Portal.Utils.wmArchG201.Factory.DispatchInSsl3(ref flag, (ref string flag_inner) =>
    {
      // creates the binding, endpoint, etc. programatically to avoid mucking with
      // SharePoint web.config.
      var wsFireWmdReading = ArchG2.Portal.Utils.wmArchG201.Factory.Get_fireWmdReading(ref flag_inner, LH, Context);
      wsFireWmdReading.fireWmdReading(readings);
    });

В этом и есть дело: когда у меня будет еще немного времени, я решу проблему с многопоточностью (или нет).

Поскольку у меня нет репутации, чтобы комментировать, я хотел бы упомянуть, что ответ Мэта Надрофски и пример кода для принудительного использования SSL3 также являются решением ошибки, похожей на

Произошла ошибка при выполнении запроса HTTP на https://xxxx/что угодно.Это может быть связано с тем, что сертификат сервера не настроен должным образом с помощью http.sys в случае HTTPS.Это также может быть вызвано несоответствием привязки безопасности между клиентом и сервером.

Просто используйте

// We're using SSL here and not TLS. Without this line, nothing workie.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

как упоминает Мат.Протестировано с сервером SAP NetWeaver PI по протоколу HTTPS.Спасибо!

Мат,

У меня тоже были такие проблемы, и у меня есть способ избежать использования certmgr.exe для добавления сертификатов в доверенный корень на удаленном компьютере.

X509Store store;
store = new X509Store("ROOT", StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);

«Объект сертификата» можно создать следующим образом:

X509Certificate2 certificate = new X509Certificate2("Give certificate location path here");
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top