BETA
Aby się zalogować, najpiew wybierz portal.
Aby się zarejestrować, najpiew wybierz portal.
Podaj słowa kluczowe
Słowa kluczowe muszą mieć co najmniej 3 sąsiadujące znaki alfanumeryczne
Pole zawiera niedozwolone znaki

Baza wiedzy











Wprowadzenie do WS-Policy

04-01-2005 20:57 | radakon
Artykuł zawiera omówienie WS-Policy, które jest częścią WSE 2.0 (Web Services Enhancements) i dotyczy definiowania zasad przesyłania wiadomości SOAP. Do artykułu dołączony jest przykład pokazujący podstawy korzystania z WS-Policy.

Zanim przejdę do głównego tematu tego artykułu, czyli WS-Policy, opiszę pokrótce WSE (Web Services Enhancements). Najprościej mówiąc WSE jest to rozszerzenie dostarczające dodatkowej funkcjonalności do Web Services. Obecnie (WSE 2.0) obejmuje implementacje następujących standardów: WS-Security, WS-SecurityPolicy, WS-Trust, WS-SecureConversation WS-Policy, WS-Referal, WS-Addressing, DIME, WS-Attachments.

 

Nad tymi oraz wieloma innymi standardami czuwa The Web Services Interoperability Organization (WS-I). Organizacja ta skupia w sobie zarówno największych producentów oprogramowania związanych z usługami Web oraz małe firmy programistyczne i użytkowników zainteresowanych tą technologią. Organizacja ta, poza opracowywaniem kolejnych standardów, gwarantuje również, że produkty wytworzone przez różnych producentów korzystających ze standardu będą ze sobą współpracować.

 

Na razie większość specyfikacji wytworzonych przez WS-I istnieje jedynie na papierze, ale dużą część dotyczącą bezpieczeństwa dostarcza nam już WSE 2.0. Wspierane jest m.in. szyfrowanie i integralność przesyłanych wiadomości,  różne sposoby zabezpieczeń, zarządzanie tokenami, mechanizmy uwierzytelniania oparte na rolach oraz zintegrowane z Windows.

 

WS-Policy jest częścią WSE 2.0, która pozwala w deklaratywny sposób określić wymagania dotyczące podpisywania oraz szyfrowania wychodzących i przychodzących wiadomości SOAP. Pozwala nam określić również rodzaj zabezpień, np. Kerberos, x509, UsernameToken, itd.

 

Przed pojawieniem się WS-Policy, tworzenie usługi Webowej korzystającej z WS-Security oznaczało konieczność napisania kodu sprawdzającego czy oczekiwane tokeny występują w przesyłanej wiadomości i czy wiadomość jest podpisana oraz zaszyfrowana w oczekiwany przez nas sposób. WS-Policy umożliwia nam osiągnięcie tego samego rezultatu w dużo prostszy sposób. Tworzony jest konfiguracyjny plik xml zawierający wymagania dotyczące przesyłania wiadomości. WSE 2.0 sam dba o weryfikację zadeklarowanych wymagań i w przypadku ich niespełnienia wyrzuca odpowiedni wyjątek.

 

W pliku konfiguracyjnym może występować wiele polis. Mogą być one zdefiniowane dla trzech różnych typów wiadomości: żądania (request), odpowiedzi (response) oraz błędu (fault). Często mogą być wzajemnie powiązane. Przykładowo polisa może wymagać, aby żądanie było podpisane cyfrowo certyfikatem x509, który następnie posłuży do zaszyfrowania odpowiedzi.

 

 

Myślę, że jesteśmy już wystarczająco przygotowani, aby zobaczyć jak używać WS-Policy. Poniżej przedstawiona jest struktura pliku xml zawierającego wymagania, co do przesyłania wiadomości SOAP.

 

<policyDocument xmlns="http://schemas.microsoft.com/wse/2003/06/Policy">

 

  <mappings>

 

    <endpoint uri="http://www.develop.com/someapp/someservice.asmx">

 

      <operation requestAction="http://www.develop.com/someapp/someservice/someop">

        <request policy="#policy1" />

        <response policy="#policy2"/>

        <fault policy="#policy3"/>

      </operation>

 

      <defaultOperation>

        <request policy="#policy4" />

        <response policy="#policy5" />

        <request fault="#policy6" />

      </defaultOperation>

 

    </endpoint>

 

  </mappings>

 

  <policies

    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"

    xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">

 

    <wsp:Policy wsu:Id="policy1">

      <!-- Policy assertions go here -->

    </wsp:Policy>

 

    <wsp:Policy wsu:Id="policy2">

      <!-- Policy assertions go here -->

    </wsp:Policy>

 

    <!-- Other policies ommitted ... -->

 

  <policies>

 

</policyDocument>

 

Głównym elementem pliku konfiguracyjnego jest policyDocument pochodzący z przestrzeni nazw http://microsoft.com/wse/2003/06/PolicyDocument. Element policyDocument dzieli się następnie na dwie główne sekcje: mappings i policies. Sekcja mappings  zawiera jeden lub więcej elementów endpoint, czyli węzłow końcowych, zawierających adres URI do usługi Web i identyfikatory nałożonych na nią polis. Natomiast sekcja policies zawiera jeden lub więcej elementów Policy, w których zdefiniowane są wymagania nałożone na przesyłane  wiadomości SOAP.

Oto główne elementy w deklaracji Policy wspierane przez WSE 2.0:

  • Integrity (cyfrowy podpis)
  • Confidentiality (szyfrowanie)
  • MessagePredicate (określa jakie elementy XML musi zawierać wiadomość SOAP)
  • MessageAge (określa czas wygaśnięcia wiadomości)
  • SecurityToken (określa wymagany token bezpieczeństwa)

To oczywiście tylko niektóre elementy. Omówienie wszystkich znajduje się w dokumentacji WSE 2.0.

 

Nadszedł czas, aby zademonstrować jak to działa. Aby to zrobić potrzebujemy mieć zainstalowane WSE 2.0. Oto adres, z którego możemy ściągnąć pakiet instalacyjny: http://msdn.microsoft.com/webservices/building/wse/default.aspx

 

Na początek stworzymy prosty Web Service i aplikację kliencką bez żadnego kodu związanego z bezpieczeństwem. Następnie użyjemy WS-Policy, aby wyegzekwować bardzo podstawowe wymagania związane z bezpieczeństwem. Przykład ma na celu pokazanie, ile pracy oszczędzamy dzięki WS-Policy i jak bardzo jest on elastyczny. Zakładam, że potrafimy stworzyć Web Service i rozumiemy podstawowe koncepcje dotyczące usług webowych.

 

Aby przykład nie był zbytnio skomplikowany, posłużymy się standardowym Web Service’em tworzonym przez Visual Studio. Postępujmy zgodnie z poniższymi krokami: 

 

1. Otwórz Visual Studio .NET i stwórz projekt ASP.NET Web Service o nazwie PolicyService.

 

2. Zmień nazwę naszej usługi z Service1 na PolicyService.

 

3. Odkomentuj przykładową Web metodę „Hello World”. Powinno to wyglądać w następujący sposób

 

[Kod C#]

    [WebMethod
    public string HelloWorld() 
    { 
        return "Hello World"
    }

4. Zapisz projekt.

 

Celowo posługujemy się najprostszą metodą, aby skupić się na głównym temacie, czyli WS-Policy. Należy podkreślić, że w tym momencie nasz Web Service nie korzysta z WSE 2.0.

 

Stwórzmy teraz naszą aplikację kliencką:

 

1. Dodaj do naszego Solution nowy projekt Windows Application i nazwij go PolicyClient.

 

2. Kliknij prawym przyciskiem na projekt i wybierz "Add Web Reference…", następnie wybierz nasz Web Service i nadaj nazwę referencji PolicyService

 

3. Dodaj nowy przycisk na formatkę i kliknij na niego dwa razy, aby oprogramować zdarzenie kliknięcia.

 

4. Dodaj następujący kod do zdarzenia:

 

[Kod C#]

    try
    {
        PolicyService.PolicyService serviceProxy = new PolicyClient.PolicyService.PolicyService();     
        MessageBox.Show(serviceProxy.HelloWorld());
    }
    catch (Exception ex)
    {
        StringBuilder sb = new StringBuilder();
        if (ex is System.Web.Services.Protocols.SoapException)
        {
            System.Web.Services.Protocols.SoapException se = ex as System.Web.Services.Protocols.SoapException;
            sb.Append("SOAP - Fault code: " + se.Code.ToString());
            sb.Append("\n\n");
        }
        sb.Append(ex.ToString());
        MessageBox.Show(sb.ToString());
    }

W tym momencie mamy w pełni działający Web Service i aplikację kliencką. Na razie nie ma tu nic interesującego, ale zaraz skonfigurujemy polisy, co umożliwi nam zrozumienie możliwości, które oferuje WS-Policy.

 

Rozszerzmy teraz naszą usługę o WS-Policy:

 

1. Kliknij prawym przyciskiem na nasz projekt PolicyService i wybierz opcję „WSE Settings 2.0…”. Opcja ta jest dostępna dopiero po zainstalowaniu WSE 2.0

 

2. Otworzy się formularz i na pierwszej zakładce ujrzysz dwa CheckBox’y. Zaznacz je oba i kliknij OK. Dzięki temu automatycznie została dodana referencja do biblioteki Microsoft.Web.Services2.dll, która zawiera wszystkie klasy dostarczające funkcjonalność WSE 2.0. Również został dodany dodatkowy wpis w pliku Web.config.

 

3. Dodaj następujące dyrektywy do pliku asmx:

 

[Kod C#]

    using Microsoft.Web.Services2;
    using Microsoft.Web.Services2.Security;
    using Microsoft.Web.Services2.Security.Tokens;

 

4. Kliknij prawym przyciskiem na projekt, wybierz „Add New Item…”, zaznacz plik typu xml, nazwij go policeCache.config i następnie go otwórz.

 

5. Oto kod, który powinien zawierać nasz plik xml:

 

<?xml version="1.0" encoding="utf-8"?>

<policyDocument xmlns="http://schemas.microsoft.com/wse/2003/06/Policy">

  <mappings>

    <endpoint uri="http://localhost/PolicyService/PolicyService.asmx">

      <defaultOperation>

        <request policy="#Sign-X.509" />

        <response policy="#Sign-Username" />

        <fault policy="" />

      </defaultOperation>

    </endpoint>

  </mappings>

  <policies xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"

            xmlns:wssp="http://schemas.xmlsoap.org/ws/2002/12/secext"

            xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">

    <!-- Zapewnienie, ze wiadomosc bedzie podpisana przy uzyciu UsernameToken -->

    <wsp:Policy wsu:Id="Sign-Username">

      <wssp:Integrity wsp:Usage="wsp:Required">

        <wssp:TokenInfo>

          <wssp:SecurityToken>

            <wssp:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</wssp:TokenType>

          </wssp:SecurityToken>

        </wssp:TokenInfo>

        <wssp:MessageParts Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body()</wssp:MessageParts>

      </wssp:Integrity>

    </wsp:Policy>

    <!-- Zapewnienie, ze wiadomosc bedzie podpisana przy uzyciu certyfikatu X509 -->

    <wsp:Policy wsu:Id="Sign-X.509">

      <wssp:Integrity wsp:Usage="wsp:Required">

        <wssp:TokenInfo>

          <wssp:SecurityToken>

            <wssp:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3</wssp:TokenType>

          </wssp:SecurityToken>

        </wssp:TokenInfo>

        <wssp:MessageParts Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body()</wssp:MessageParts>

      </wssp:Integrity>

    </wsp:Policy>

  </policies>

</policyDocument>

Co prawda w ustawieniach WSE znajduje się zakładka Policy i jest tam generator pliku konfiguracyjnego, ale jak dla mnie jest on mało intuicyjny i wolę samemu wypełnić plik xml z naszymi wymaganiami.

 

Powinieneś rozpoznać główne elementy, które wystąpiły na początku tego tekstu w schemacie pliku konfiguracyjnego. Jeśli nie rozumiesz niektórych elementów nie powinieneś się tym martwić. Najważniejsze jest, abyś prześledził ten plik i zrozumiał ogólnie, co jest w nim zawarte. Opisy wszystkich elementów znajdziesz w dokumentacji WSE 2.0.

 

Generalnie stworzyliśmy dwie różne polisy. Pierwsza odpowiedzialna za wymaganie, aby wiadomość była podpisana przy użyciu UsernameToken, druga natomiast wymaga, aby wiadomość była podpisana wykorzystując X509SecurityToken. W części mappings mamy natomiast zdefiniowany węzeł końcowy, czyli nasz Web Service oraz wymaganie aby wiadomości z żądaniami używały X509SecurityToken, natomiast odpowiedzi wykorzystywały UsernameToken.

 

Do tej pory udało nam się już stworzyć plik konfiguracyjny, ale w żaden sposób nie jest on powiązany z naszą usługą. Dlatego, aby zaczął on obowiązywać musimy dokonać odpowiedniego wpisu do pliku Web.config.

 

6. Otwórz plik Web.config i znajdź w nim element <microsoft.web.services2>

 

7. Dodajmy następujące podelementy:

 

<policy>

  <cache name="policyCache.config" />

</policy>

<security>

  <x509 allowTestRoot="true" allowRevocationUrlRetrieval="false" verifyTrust="false" storeLocation="LocalMachine"/>

</security>

 

Zauważ, że element policy łączy nasz plik konfiguracyjny z naszym Web Service’em. Natomiast element security jest niezbędny ze względu na to, że wykorzystujemy do cyfrowego podpisu X509SecurityToken. Brak tego elementu powodowałby wystąpienie błędu SOAP.

 

Jeśli teraz uruchomilibyśmy klienta i spróbowali skorzystać z naszej usługi, WSE wyrzuciłby nam wyjątek z powodu nie spełnienia wymagań zdefiniowanych w pliku policyCache.config.

 

Dlatego musimy zrobić jeszcze jedną rzecz w naszej usłudze webowej. W pliku Policy ustawiliśmy, że odpowiedź musi być podpisana z wykorzystaniem UsernameToken, w związku z czym musimy odrobinę zmodyfikować naszą metodę HelloWorld.

 

[Kod C#]

    [WebMethod]
    public string HelloWorld()
    {
        UsernameToken token = new UsernameToken("Username", "Password", PasswordOption.SendPlainText);
        ResponseSoapContext.Current.Security.Tokens.Add(token);
        ResponseSoapContext.Current.Security.Elements.Add(new MessageSignature(token));
        return "Hello World";
    }

 

Zmień atrybuty „Username” i „Password” w konstruktorze UsernameToken na takie, żeby się zgadzały z danymi użytkownika na lokalnym komputerze. Hasło w tym przykładzie jest przesyłane otwartym tekstem ponieważ nie na tym skupia się ten artykuł.

 

Należałoby teraz jeszcze zmienić naszego klienta, aby spełniał wymagania zdefiniowane w naszym pliku Policy. Określiliśmy w nim, że żądanie musi być podpisane przy użyciu X509SecurityToken. Zanim jednak przejdziemy dalej, musimy posiadać jakiś certyfikat, przy pomocy którego będziemy podpisywać żądania. Do tego przykładu proponuję zainstalować certyfikaty dołączone do WSE 2.0. W dokumentacji opisany jest proces ich instalacji.

Jak już będziemy mieli dostępne certyfikaty przejdźmy do modyfikacji naszej aplikacji klienckiej.

 

1. Po pierwsze klient również musi mieć włączone WSE 2.0, dlatego kliknij prawym przyciskiem na projekt klienta i wybierz „WSE Settings 2.0…” po otworzeniu formatki należy zaznaczyć dostępnego CheckBox’a

 

2. Dodaj następujące dyrektywy do kodu formatki:

 

[Kod C#]

    using Microsoft.Web.Services2.Security;
    using Microsoft.Web.Services2.Security.Tokens;
    using Microsoft.Web.Services2.Security.X509;

 

3. Przejdź na widok klas projektu aplikacji klienckiej, otwórz plik z klasą PolicyService i zmień klasę bazową z:

 

System.Web.Services.Protocols.SoapHttpClientProtocol

 

na

 

Microsoft.Web.Services2.WebServicesClientProtocol

 

4. Dodaj do kodu formatki następującą metodę:

 

[Kod C#]

    private X509SecurityToken GetX509Token()
    {
        // Klucz ten pochodzi z certyfikatu dolaczonego do WSE 2.0
        string keyId = "bBwPfItvKp3b6TNDq+14qs58VJQ=";

        X509SecurityToken token = null;
        X509CertificateStore store = X509CertificateStore.CurrentUserStore(X509CertificateStore.MyStore);

        if (!store.OpenRead())
            return null;

        X509CertificateCollection certificates = store.FindCertificateByKeyIdentifier(Convert.FromBase64String(keyId));

        if (certificates.Count > 0)
            token = new X509SecurityToken(certificates[0]);
        return token;
    }

 

Metoda ta zwraca token X509SecurityToken pobrany z X509CertificateStore

 

5. Przejdź teraz do obsługi zdarzenia kliknięcia w nasz przycisk i podmień kod w     bloku try{…} na następujący

 

[Kod C#]

    PolicyService.PolicyService serviceProxy = new PolicyClient.PolicyService.PolicyService();
    X509SecurityToken token = GetX509Token();
    if (token == null)
        throw new Exception("Couldn’t find X509 Certificate.");

    serviceProxy.RequestSoapContext.Security.Tokens.Add(token);
    serviceProxy.RequestSoapContext.Security.Elements.Add(new MessageSignature(token));

    MessageBox.Show(serviceProxy.HelloWorld());

 

W tej chwili żądanie ze strony klienta będzie już podpisane cyfrowo. Będą również spełnione  zadeklarowane wymagania i klient powinien móc bez problemu korzystać z naszej usługi. Generalnie podpisanie wiadomości polega, po pierwsze na dodaniu uzyskanego SecurityToken do kolekcji RequestSoapContext.Security.Tokens, a następnie dołączeniu MessageSignature bazującego na SecurityToken do kolekcji RequestSoapContext.Security.Elements.

 

Mam nadzieję, że ten prosty przykład przybliżył wam zagadnienia związane z WS-Policy i zarazem pokazał ile pracy dzięki temu możemy zaoszczędzić.

 

Dla osób pragnących poszerzać swoją wiedzę w zakresie tego tematu polecam materiały z których korzystałem:

·        Dokumentacja do WSE 2.0 (polecam dołączone przykłady – wiele spraw mogą rozjaśnić)

·        „Świat jako usługa” – Tomasz Kopacz - http://www.computerworld.pl/artykuly/43492.html

·        Web Services Enhancements 2.0 Support for WS-Policy - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwse/html/wse2wspolicy.asp

·        Understanding WS-Policy - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwebsrv/html/understwspol.asp

 

Załączniki:

Podobne artykuły

Komentarze 1

Treku
Treku
1 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0

Cześć Konrad,

fajne wprowadzenie w dość mało rozeznaną tematykę, mam nadzieję, że kiedyś użyję tego w przyszłości :) ocene znasz ;)

Pozdrawiam,
Piotr
ps. zapraszam do mnie: http://www.codeguru.pl/Default.aspx?Page=Articles/Details&pubid=355

pkt.

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.