Подтвердить что ты не робот

Внедрить клиент С#, который использует WebServices через SSL?

Итак, у меня есть ServiceReference, добавленный в приложение консоли С#, которое вызывает веб-службу, которая открывается из 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 для его регистрации?

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

4b9b3361

Ответ 1

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

Итак.

Коренная проблема заключалась в том, что по умолчанию 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 Compiler, чтобы превратить этот прокси-класс в библиотеку (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;

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

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

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

Надеюсь, этот ответ поможет некоторым людям. Благодарим вас за помощь и помощь в этом вопросе.

Ответ 2

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

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

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

Ответ 3

Mat,

У меня тоже были такие проблемы, и у меня есть способ избежать использования 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");

Ответ 4

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

Учитывая статический класс "Factory", укажите эти два элемента:

/// <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);
    });

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

Ответ 5

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

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

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

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

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