Nowe funkcjonalności usług sieciowych Czyli następny krok w usługach Web Tomasz Kopacz
Plan Stan technologii związanej z usługami Web Do czego służy WSE? I jak działa WSE 1.0 w działaniu Podpis Kodowanie Routing Załączniki Inne elementy związane z GXA
Problem Co oferują usługi Web Dobrze opracowana warstwa transportowa HTTP HTTPS? Jasno zdefiniowany sposób wywoływania, przekazywania parametrów, odbierania wyników SOAP Łatwość ręcznej modyfikacji XML Czego może jeszcze brakować: Mechanizmu podpisu pakietu Szyfrowania (innego niż w warstwie transportowej) Sensownej obsługi załączników Zasady przekazywania komunikatów SOAP pomiędzy węzłami Transakcji
WSE dostępne możliwości WS-Security Podpisy cyfrowe Kodowanie Czyli: autoryzacja i identyfikacja WS-Routing Przesyłanie pakietu SOAP pomiędzy usługami Niezależność od topologii Klient nie musi komunikować się bezpośrednio z usługą! Łatwe serwisowanie właściwej usługi Przeźroczyste dla klienta WS-Attachments Dokładniej: DIME Wreszcie elegancko załączniki binarne
Jak to działa Zestaw filtrów zgodnych ze standardami Można dodać własne filtry Pozwala analizować elementy nagłówka SOAP Wejściowe/Wyjściowe Dekodowanie – dopiero u ostatecznego odbiorcy
Narzędzia i uwagi Web Services Enhancements 1.0 SP1 for Microsoft.NET (WSE) WSE Settings Tool for Visual Studio.NET Warto ściągnąć (MSDN) Automatyczna modyfikacja Proxy Edytor plików konfiguracyjnych Wygodne! Jeżeli decydujemy się na WSE – wtedy lepiej by każda usługa z tego rozszerzenia korzystała Routing niemożliwy do starej usługi Web
Istotne przestrzenie nazw Klient: Microsoft.Web.Services Serwer: System.Web.Services Dodatkowe usługi: Microsoft.Web.Services.Configuration Microsoft.Web.Services.Diagnostics Microsoft.Web.Services.Dime Microsoft.Web.Services.Referral Microsoft.Web.Services.Routing Microsoft.Web.Services.Security Microsoft.Web.Services.Security.X509.X509Certificates ( część funkcji dziedziczy z System.Security.Cryptography.X509Certificates ) Microsoft.Web.Services.Timestamp
Część I Podpis cyfrowy Kodowanie
O certyfikatach Cryptography Service Providers (CSPs) Implementuje Cryptography API Np: Microsoft Base Cryptographic Provider v1.0 CSP ma bazę do przechowywania kluczy Klient musi do niej sięgać Algorytmy symetryczne i asymetryczne Tu - interesujące 2 operacje – kodowanie i podpis
Certyfikaty potrzebne w przykładzie Klient: Klucz prywatny (własny) Klucz publiczny (serwer) Server Klucz publiczny (klienta, do identyfikacji) Klucz prywatny (serwer, do odkodowania)
Skąd certyfikat? Kupić Verisign? Wygenerować np. Certification Services (serwer NT/2000/2003) Platform SDK, CreateCert Prawie Certification Services Testowy makecert -ss My -sr LocalMachine –pe -sk Signature -n "CN=DD2003CLIENT" Narzędzie z.NET 1.1 ! Opcje -ss, -sr – pojemnik -pe – klucz prywatny eksportowalny -sk
Usługa Web 1. Instalacja filtra WSE; odpowiednia referencja 2. Określenie zasad wyszukiwania certyfikatów Lub ręczne zarządzanie 3. Śledzenie (upraszcza ) 4. KONIEC ZMIAN Usługi Web pisze się tak samo Można ew. odwołać się do SoapContext i sprawdzić: Podpis (identyfikacja klienta) Czy paczka została zakodowana Dopisać informacje o kodowaniu odpowiedzi
Sekcja w pliku Rejestracja nowej sekcji do pliku konfiguracyjnego Dotyczy także klienta (o ile coś zmienia w konfiguracji po swojej stronie) [tu ustawienia]
Instalacja filtra WSE Plik DLL – może się znajdować w folderze BIN <add type= " Microsoft.Web.Services.WebServicesExtension, Microsoft.Web.Services,Version= , Culture=neutral, PublicKeyToken=31bf3856ad364e35" priority="1" group="0"/>
Zasady wyszukiwania certyfikatów Plik konfiguracyjny: Web.config lub NazwaPliku.Exe.config Prawa do C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto[...] <x509 storeLocation="LocalMachine|CurrentUser" verifyTrust="true|false" allowTestRoot="true|false" allowRevocationUrlRetrieval="true|false" allowUrlRetrieval="true|false" />
Warto - śledzenie Analiza pakietu SOAP Dopisek w pliku konfiguracyjnym Ew. klasy TraceInputFilter/TraceOutputFilter […]
Serwer - analiza SoapContext Do analizy głównie Security.Tokens public string GetPriceAndDescription(int kod) { SoapContext rc=HttpSoapContext.RequestContext; X509SecurityToken tok; foreach (SecurityToken tmp in rc.Security.Tokens) { tok= tmp as X509SecurityToken; if (tok!=null) { //Coś sprawdzamy
Wywołanie 1. Referencja do biblioteki WSE 2. Zmiana klasy proxy Lub – to zrobi WSE Settings Tool 3. Dodanie odpowiedniej sygnatury/informacji o kodowaniu do konetstu SOAP 4. Wywołanie – dokładnie tak samo jak zwykłą usługę
Zmiana klasy Proxy klienta Zmiana klasy bazowej (Show All Files – modyfikacja w odpowiednim pliku references.cs/references.vb w danej usłudze Web) Jeżeli zainstalowane WSE Settings Tool for Visual Studio.NET zmiany automatyczne po dodaniu referencji do usługi 2 klasy: nazwaUsługi i nazwaUsługiWse public class Check : System.Web.Services.Protocols.SoapHttpClientProtocol {...} public class Check : Microsoft.Web.Services.WebServicesClientProtocol {...}
Sygnatura Pobrać kontekst SOAP z danej usługi Web Utworzyć token bezpieczeństwa dla wybranego certyfikatu; dodać go do SoapContext Stworzyć sygnaturę na podstawie tokena Dodać sygnaturę do SoapContext Określić dozwolony czas życia pakietu SOAP SoapContext cnt=ws.RequestSoapContext; X509SecurityToken tokSign=new X509SecurityToken(SelCertSign); cnt.Security.Tokens.Add(tokSign); Signature sign=new Signature(tokSign); cnt.Security.Elements.Add(sign);
Kodowanie Pobrać kontekst SOAP z danej usługi Web Utworzyć token bezpieczeństwa dla wybranego certyfikatu; dodać go do SoapContext Stworzyć obiekt odpowiedzialny za kodowanie Dodać sygnaturę do SoapContext Określić dozwolony czas życia pakietu SOAP SoapContext cnt=ws.RequestSoapContext; X509SecurityToken tokEnc= new X509SecurityToken(SelCertEnc); cnt.Security.Tokens.Add(tokEnc); EncryptedData ed=new EncryptedData(tokEnc); cnt.Security.Elements.Add(ed);
DEMO I WSSign Wybór certyfikatu Podpis pakietu SOAP
A może bez X.509? X.509 wymaga PKI Może być kłopotliwe: Zarządzanie certyfikatami, CLR, Dystrybucja, CA itp. Ale – łatwa współpraca z innymi środowiskami (IBM WSTK) : Artykuł: Web Services Enhancements 1.0 and Java Interoperability Można zrobić inaczej - ręcznie Kodowanie Własny token odpowiedzialny za zakodowanie/zdekodowanie informacji Sygnatura UsernameToken Hasło nie przesyłane (obie strony muszą go znać) (SendNone) Hasło przesyłane jako SHA-1 (SendHashed) Czystym tekstem (SendPlainText) – lepiej nie; bo bez SSL – pozorne zabezpieczenie Lub - własny token
Podpis - szczegóły Implementacja IPasswordProvider public string GetPassword(UsernameToken token) Zwraca hasło dla danego użytkownika (baza?) Rejestracja nowego passwordProvider Usługa Web wyszukuje UsernameToken w HttpSoapContext.RequestContext.Security.Tokens Klient – tworzy UsernameToken […]
Kodowanie - kolejność operacji Klient konstruuje token i przekazuje: Klucz publiczny do zakodowania pakietu Informację o sposobie dekodowania Tu – ścieżkę do pliku na serwerze zawierającą klucz prywatny Można także mapować po kluczu publicznym/nazwie itp. Dodaje informacje do Security.Tokens i Security.Elements Wywołuje usługę Web Server Analizuje Analizuje ValueType i wybiera klasę która obsługuje token i informuje o tym jak znaleźć klucz dekodujący Dekoduje pakiet Wywołuje odpowiednią funkcjonalność
Kodowanie - generowanie klucza Można wykorzystać CryptoAPI System.Security; System.Security.Cryptography; m_rsa=new RSACryptoServiceProvider(1024); Wynik można zapisać do XML-a Tylko klucz publiczny Klucz publiczny i prywatny
Ręczne kodowanie I MySecurityToken, dziedziczy z BinarySecurityToken NamespaceURI - własna przestrzeń nazw XmlQualifiedName TokenValueType określający typ tokena (identyfikowane przy przetwarzaniu przez WSE) Klasa opakowuje RSACryptoServiceProvider Najważniejsze funkcje: DecryptionKey/EncryptionKey SignatureKey/AuthenticationKey (własna sygnatura) Konstruktor: MySecurityToken(XmlElement element) LoadXml()
Ręczne kodowanie II MySecurityTokenDecryptionProvider dziedziczy z DecryptionKeyProvider public override DecryptionKey GetDecryptionKey(string algorithmUri,KeyInfo keyInfo) Zwraca klucz do dekodowania na podstawie URI oraz struktury KeyInfo (wypełnionej przez klienta wysyłającego SOAP) Konfiguracja:
Wywołanie – kodowanie i sygnatura Podpis i autoryzacja Kodowanie SoapContext cnt= ws.RequestSoapContext; UsernameToken ut= new UsernameToken(txtUser.Text,txtPassword.Text, PasswordOption.SendNone); cnt.Security.Tokens. […] cnt.Security.Elements[…] string pubkey; [odczyt z pliku] MySecurityToken.MySecurityToken tok=new na serwerze",pubkey); cnt.Security.Tokens. […] cnt.Security.Elements[…]
DEMO II Ręczne dekodowanie Ręczny podpis
Kodowanie odpowiedzi serwera Analogicznie jak robi to klient HttpSoapContext.ResponseContext Dodawanie Security.Tokens Dodawanie Security.Elements Przekazanie klucza? X509 Własny BinarySecurityToken Zapis do RawData Swój klucz publiczny którym ma być zakodowany pakiet zwrotny Wskaźnik który pozwoli dopisać do pakietu SOAP informacje jak odkodować pakiet po stronie klienta. RawData zapisywany jako XmlElement (i konstruktor go odtworzy
DEMO III (prawie demo ) Własny podpis i kodowanie odpowiedzi serwera Polecam samodzielne obejrzenie przykładów Analogiczny przykład jak poprzednio Dodatkowe informacje zapisywane w RawData
Część II Routing
Większa elastyczność Dodatkowy pośrednik Można łatwo przekierować usługę na zapasowy serwer i np. spokojnie zmienić bazowy kod Routowanie w zależności od nagłówka Np. – serwis dla klientów i sprzedawców Z różnymi cenami itp..
Prosty routing I Zmiany tylko w web.config – nie w aplikacji Dodatkowy handler <add verb="*" path="*.asmx" type="Microsoft.Web.Services. Routing.RoutingHandler, Microsoft.Web.Services, Version= , Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
Prosty routing II Określenie pliku zawierającego definicję routingu (*.config) Nie można łatwo uzyskać dostępu z zewnątrz Należy dać prawa do zapisu Podmiana Modyfikacja web.config (inny referal) Zmiana właściwego pliku Ponowna modyfikacja web.config Ręcznie modyfikować proxy by wskazywała na usługę
Definicja routingu Nie zapomnieć o przestrzeni nazw: [WebService(Namespace=" konkretnego")] Mapowanie po:, <r:referrals xmlns:r=" uuid:fa[...] […]
Analiza nagłówka Klasa dziedzicząca z RoutingHandler Inny proces obsługujący pliki *.ashx: Może być *.asmx public class MyRoutingHandler : RoutingHandler {…} […]
W środku MyRoutingHandler Klasa ma dziedziczyć z RoutingHandler ProcessRequestMessage ProcessResponseMessage Można: Pobrać i sprawdzić podpis, autoryzować użytkownika itp. Ale wystarczy: Sprawdzenie czy jest UserNameToken Wtedy wiadomo że obecna jest inf. o autoryzacji Funkcja otrzymuje SoapEnvelope analiza pakietu XML i wybranie odpowiedniego elementu
Własny routing - implementacja Własne MyRouting dziedziczące z RoutingHandler protected override void ProcessRequestMessage( SoapEnvelope message, Path outgoingPath) { XmlNamespaceManager ns = new XmlNamespaceManager(new NameTable()); ns.AddNamespace("wsse",[…]"); int cnt=message.Header.SelectNodes ("wsse:Security/wsse:UsernameToken",ns).Count; Via target=null; if (cnt==0) target=new Via(new Uri(" else target=new Via(new Uri(" outgoingPath.Fwd.Insert(0, target);
DEMO IV Przykład routingu Można też zagnieżdżać routing Klient koduje i wysyła pakiet do uniwersalnej usługi (Routing_simple). Usługa (dokładniej – odpowiednia konfiguracja) przekierowuje pakiet do (Routing_Complex) Analiza uprawnień (obecność UsernameToken) Docelowa usługa WSSign_Username Sprawdza autoryzację Jak zła – odrzuca pakiet Dekoduje pakiet Generuje odpowiedź PublicInfo Zwraca publiczną cenę
Część III Załączniki i DIME
WS-Attachments i DIME Problem: zwrócić zdjęcie (kod paskowy itp.)… Zakodować Base64, ręcznie, nagłówki…. Można uprościć: WS-Attachments i DIME Klient: Uwaga! Załączniki nie są kodowane SoapContext rc = HttpSoapContext.ResponseContext; DimeAttachment dm = new DimeAttachment( "image/gif", TypeFormatEnum.MediaType, "C:\\test.gif"); rc.Attachments.Add(dm); img.Image = new Bitmap( ws.ResponseSoapContext.Attachments[0].Stream);
Pokaz Formatka wyświetlająca GIF z obrazem zwracanym przez usługę Web
DIME – kilka szczegółów DimeRecord – jednostka opisu DIME DimeReader/DimeWriter – strumień rekordów Do używania: DimeAttachment (sekwencja rekordów DIME) Stream – strumień pliku ID ChunkSize – ostrożnie 500MB rysunek na serwerze…. Type/TypeFormat Zwykle MediaType Konstruktor Typ (string) – zwykle typ MIME
Przyszłość Transakcje WS-Transaction Biztalk? Zarządzanie uprawnieniami i zasadami zabezpieczeń WS-Policy
Uwagi końcowe Prezentacja + przykłady do ściągnięcia dostępne na entacje.asp entacje.asp Pytania: odpowiedzi (raczej) szybko