2009-05-12 21 views
12

Więc mam ServiceReference dodane do aplikacji C# Console, która wywołuje usługę sieci Web, która jest narażona na Oracle.Wdrożenie klienta C# korzystającego z usług WebServices przez SSL?

Mam wszystko ustawione i działa jak brzoskwinie, gdy nie używa SSL (http). Próbuję skonfigurować go przy użyciu protokołu SSL teraz i mam problemy z dodaniem go do Odwołania do usługi (lub nawet do odnośników internetowych). Na przykład adres URL (https), na którym usługa jest wyświetlana, nie zwraca odpowiednich metod internetowych podczas próby dodania go do programu Visual Studio.

Podstawowe połączenie zostało zamknięte: Wystąpił nieoczekiwany błąd podczas wysyłania. Otrzymano nieoczekiwany EOF lub 0 bajtów ze strumienia transportowego. Metadane zawiera odniesienie, które nie mogą zostać rozwiązane: „https://srs204.mywebsite.ca:7776/SomeDirectory/MyWebService?WSDL

Kolejny kłopot mam to w odniesieniu do zarządzania certyfikatami i wdrażania. Mam około 1000 zewnętrznych stron klienckich, które będą musiały używać tego małego narzędzia i będą potrzebować certyfikatu zainstalowanego w odpowiednim magazynie certyfikatu, aby połączyć się z usługą sieciową. Nie jestem pewien, jak najlepiej sobie z tym poradzić. Czy muszą znajdować się w głównym magazynie?

Spędziłem kilka godzin w Internecie, przeglądając różne opcje, ale nie można uzyskać dobrej czystej odpowiedzi w dowolnym miejscu.

Podsumowując, mam kilka pytań tutaj:

1) Ktoś ma jakieś dobre linki na tworzeniu Web Services w Visual Studio, które używają protokołu SSL?

2) Jak zarejestrować certyfikat? W którym sklepie powinien on istnieć? Czy mogę po prostu użyć czegoś podobnego do CertMgr, aby go zarejestrować?

Musi być dobra książka/samouczek/cokolwiek, co pokaże mi, jakie są dobre praktyki w ustalaniu czegoś takiego. Po prostu nie mogę tego znaleźć!

+0

Czy skontaktowałeś się z osobą, która utworzyła witrynę, aby zobaczyć, jak jest skonfigurowana? –

+0

W tym momencie są w tym samym budynku, więc jeśli jest to coś związanego z serwerem, mogę to zmienić. Mogę podnieść URL https w przeglądarce i pokazuje mi standardową stronę testowania usług Oracle Web Service. Więc mogę to uderzyć. Po kliknięciu tego adresu URL pojawia się prośba o zaakceptowanie certyfikatu. Dostarczono mi dwa pliki .cer (jeden dla serwera programistycznego, jeden dla serwera produkcyjnego), który będzie musiał zostać zarejestrowany. –

+1

Jeśli otworzysz adres URL (https) w przeglądarce, czy widzisz, czego oczekujesz? Czy inni używają tej usługi przez HTTPS bez problemu? Nie jestem pewien, jak działają serwery WWW Oracle, ale jeśli są hostowane w usługach IIS lub za ich pośrednictwem, musisz dodać nazwę domeny (webservice.servicehost.com) jako nagłówek hosta SSL. – Nate

Odpowiedz

28

Cóż, wymyśliłem to. Zajęło mi to znacznie dłużej, niż dbam o to mówić, ale chciałem podzielić się moim rozwiązaniem, ponieważ jest to OGROMNA gra dla zwierząt domowych, aby zobaczyć standard. "Och, naprawiłem to! Dzięki!" posty, które pozostawiają wszystkich w zawieszeniu na tym, co faktycznie się wydarzyło.

So.

Główny problem polegał na tym, że Visual Studio 2008 domyślnie używa protokołu TLS do uzgadniania SSL, a usługa sieci Web oparta na Oracle/Java, z którą próbowałem się połączyć, używała SSL3.

Podczas korzystania z "Dodaj odniesienie do usługi ..." w Visual Studio 2008, masz no way to specify that the security protocol, menedżer punktów usług powinien być SSL3.

O ile.

Użytkownik przyjmuje statyczny dokument WSDL i use wsdl.exe to generate a proxy class.

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

Następnie można użyć C Sharp Compiler aby włączyć tę klasę proxy do biblioteki (.dll) i dodać go do swoich projektów Net „Referencje”.

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

W tym miejscu trzeba także upewnić się, że masz włączone System.Web.Services na liście „zewnętrzne”, jak również.

Teraz powinieneś być w stanie zadzwonić do usługi internetowej bez problemu w kodzie. Aby to zrobić, będziesz potrzebował jednej magicznej linii kodu przed utworzeniem usługi.

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

OK, więc byłem pod wrażeniem samego siebie, ponieważ testowanie było świetne na moim komputerze. Następnie został wdrożony w innym polu klienta i nie nawiązywał połączenia z powodu problemu z uprawnieniami/autoryzacją. To pachniało jak certyfikaty (cokolwiek pachną). Aby rozwiązać ten problem, I used certmgr.exe, aby zarejestrować certyfikat witryny do Zaufanego katalogu głównego na komputerze lokalnym.

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

Pozwala mi to rozpowszechnić certyfikat na naszych stronach klientów i zainstalować go automatycznie dla użytkowników. Nadal nie jestem pewien, w jaki sposób "przyjazne dla bezpieczeństwa" będą różne wersje okien w odniesieniu do automatycznych rejestracji certyfikatów, takich jak ten, ale do tej pory działało świetnie.

Mam nadzieję, że ta odpowiedź pomaga niektórym osobom. Dzięki blowdart za całą twoją pomoc na ten temat i dostarczając trochę wglądu.

+1

Zawsze odpowiedz na własne pytania, jeśli je wymyślisz. Uratowałeś mnie, proszę pana. (Miałem serwer internetowy reklamujący obsługę TLS. Przekonałem się, że to nieprawda!) – DFTR

+0

Właśnie przeglądałem SO. Naprawdę nie miałem na to pytania, ale bardzo się cieszę, że widzę twoją rezolucję. Brzmiało to tak, jakby wymagało to wielu badań. Świetne wyjaśnienie! Dzięki! – jason

+0

Bardzo miło było usłyszeć, że pomogłem komuś i mam nadzieję, że uratowałem trochę bólu! :) –

4

Wygląda na to, że usługa sieciowa używa certyfikatu z podpisem własnym. Szczerze mówiąc to nie jest najlepsze podejście.

Zakładając, że jesteś dużą organizacją i możesz ją skonfigurować, możesz ustawić własny zaufany ośrodek certyfikacji, co jest szczególnie łatwe dzięki Active Directory. Z tego urzędu certyfikacji serwer obsługujący usługę Oracle może zażądać certyfikatu i można użyć zasad usługi AD, aby zaufać certyfikatowi głównego urzędu certyfikacji, umieszczając go w zaufanym katalogu głównym magazynu maszyny. To usunie potrzebę ręcznego zaufania lub akceptacji certyfikatu w serwisie WWW.

Jeśli komputery klienckie są urządzeniami zewnętrznymi, będziesz musiał skłonić pracowników do ujawnienia usługi, aby albo zakupili "rzeczywisty" certyfikat od jednego z dobrze znanych ośrodków certyfikacji, takich jak Verisign, Thawte, GeoTrust itp. Lub jako część pakietu instalacyjnego, certyfikat publiczny i zainstaluj go w urzędach certyfikacji Trusted Root na poziomie komputera na każdym komputerze. Ma to problemy, na przykład nie można odwołać certyfikatu, ale usunie monit.

+0

Dzięki za odpowiedź! Dostałem dwa certyfikaty. Jeden dla serwera "rozwoju" i drugi dla serwera "produkcyjnego". Nasze strony klientów są zewnętrzne, więc muszę się martwić ręczną rejestracją certyfikatów. Jakieś dobre linki na najlepszy sposób, aby dostać je do zaufanego magazynu maszyn root? Certyfikat produkcyjny pochodzi z GTE CyberTrust i jest certyfikatem Global Root obejmującym wszystkie zasady wydawania i wszystkie zasady dotyczące aplikacji. –

+1

Więc nie musisz martwić się o serwer na żywo, to zadziała po wyjęciu z pudełka, ponieważ GTE jest zaufanym rootem (myślę, że jesteś trochę zdezorientowany - jest mało prawdopodobne, że serwer live ma własny certyfikat root, to jest prawdopodobnie zwykły certyfikat). Aby sprawdzić, dodam odwołanie do usługi na żywo i zobaczę, co się stanie. Jeśli to wszystko jest dobre, to dla dev wystarczy zainstalować certyfikat na swoim komputerze. Uruchom program MMC i dodaj przystawkę certyfikatów, informującą o konieczności użycia komputera lokalnego. Następnie zaimportuj certyfikat dev do zaufanego katalogu głównego. – blowdart

+0

Gotcha. Uruchomiłem MMC, użyłem przystawki certyfikatów, aby upewnić się, że uprawnienia do certyfikatu rozwoju zostały dodane do "zaufanego katalogu głównego" na komputerze lokalnym. Nadal nie można połączyć się z wersją rozwojową usługi. Nie mogę przetestować wersji produkcyjnej, ponieważ nie jesteśmy jeszcze na etapie rozwoju. Być może uda mi się nakłonić ich, by spróbowali coś dla mnie zrobić. Czy jest szansa, że ​​coś może być nie tak z końcem z certyfikatem rozwoju? Jeśli mam zainstalowany odpowiedni certyfikat w moim systemie, powinienem móc dodać odwołanie do usługi HTTPS bez błędu, prawda? –

1

Mat,

miałem takich problemów i nie mam zbyt drogi, aby uniknąć używania certmgr.exe dodać certyfikaty zaufanego korzenia na zdalnej maszynie.

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

do „obiekt świadectwo” mogą być tworzone tak:

X509Certificate2 certificate = new X509Certificate2("Give certificate location path here"); 
+0

Hej dzięki za odpowiedź! Już wdrożyliśmy do naszych stron klientów za pomocą niestandardowego skryptu korzystającego z narzędzia certmgr.exe, ale to rozwiązanie jest o wiele lepsze. Zrobimy to, gdy cofniemy się do tego kodu następnym razem, gdy nastąpi zmiana. –

1

Dzięki za ten wielki cynk, wziął szybki rozejrzeć po swoje rzeczy i masz dużo dobrych pomysłów dzieje. Oto moja mała rzecz do dodania - zajmuję się webMethods i (niespodzianka!) Ma te same problemy co serwer aplikacji Oracle, z którym się łączyłeś (SSL3 zamiast TLS). Twoje podejście działało świetnie, oto mój addendum.

danej klasy statyczne „Fabryka” dostarczyć te dwie handy-dandy elementy:

/// <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 { } 
    } 
    } 
} 

A potem konsumować te rzeczy (jak nie masz wątpliwości już domyślić, ale umieścić rolki bębna tu w każdym razie) :

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

To wystarczy - gdy dostanę trochę więcej czasu, rozwiążę problem z gwintowaniem (lub nie).

+0

+1 - Awesome. Czasami trudno jest znaleźć te rodzaje niejasnych błędów i poprawek. Dzięki za publikację i nagrody! –

1

Ponieważ nie mam reputację swoich uwag, chciałbym wspomnieć, że odpowiedź i przykładowy kod Mat Nadrofsky za zmuszanie SSL3 to również rozwiązanie dla błędu podobny do

Wystąpił błąd podczas dokonywania Żądanie HTTP do https://xxxx/whatever. Może to wynikać z faktu, że certyfikat serwera nie jest skonfigurowany prawidłowo z HTTP.SYS w przypadku HTTPS . Może to być również spowodowane niezgodnością powiązania zabezpieczeń między klientem a serwerem.

Wystarczy użyć

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

jak wspomniano przez Mat. Testowany z serwerem SAP NetWeaver PI w HTTPS. Dzięki!

+0

Hej, dzięki za wysyłkę i cieszę się, że mogę pomóc! :) –

Powiązane problemy