Kontrola dostępu w aplikacjach webowych



Podobne dokumenty
REFERAT O PRACY DYPLOMOWEJ

Wzorce Strukturalne. Adapter: opis. Tomasz Borzyszkowski

Temat: Ułatwienia wynikające z zastosowania Frameworku CakePHP podczas budowania stron internetowych

PHP 5 język obiektowy

Sesje, ciasteczka, wyjątki. Ciasteczka w PHP. Zastosowanie cookies. Sprawdzanie obecności ciasteczka

Budowa aplikacji ASP.NET z wykorzystaniem wzorca MVC

Aplikacje w środowisku Java

Grzegorz Ruciński. Warszawska Wyższa Szkoła Informatyki Promotor dr inż. Paweł Figat

Klasy abstrakcyjne i interfejsy

Programowanie obiektowe

EXSO-CORE - specyfikacja

Programowanie obiektowe

Wzorce projektowe cz. II. Wzorce projektowe cz. II 1/35

Zaawansowane programowanie obiektowe - wykład 5


Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody

Wprowadzenie do programowania aplikacji mobilnych

Wprowadzenie do projektu QualitySpy

Rozdział 4 KLASY, OBIEKTY, METODY

TEMAT : KLASY DZIEDZICZENIE

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

Programowanie obiektowe

Programowanie obiektowe

Projekt dotyczy stworzenia zintegrowanego, modularnego systemu informatycznego wspomagającego zarządzanie pracownikami i projektami w firmie

Firma Informatyczna ASDER. Prezentacja. Serwer danych lokalnych. Przemysław Kroczak ASDER

10. Programowanie obiektowe w PHP5

Możliwość dodawania modułów pozwala na dopasowanie oprogramowania do procesów biznesowych w firmie.

Projektowanie obiektowe. Roman Simiński Wzorce projektowe Wybrane wzorce strukturalne

Platforma e-learningowa

Przykładowa implementacja

Warstwa integracji. wg. D.Alur, J.Crupi, D. Malks, Core J2EE. Wzorce projektowe.

Forum Client - Spring in Swing

B2B Obsługa portalu zgłoszeniowego

Programowanie Obiektowe Ćwiczenie 4

Podstawy programowania III WYKŁAD 4

Plik pobrano z Tytuł: Wzorce projektowe, cz. 2 Strategy Ostatnia aktualizacja:

Wzorce prezentacji internetowych

Kurs WWW. Paweł Rajba.

Dzisiejszy wykład. Wzorce projektowe. Visitor Client-Server Factory Singleton

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ),

Zarządzanie reklamacjami i serwisem w programie bs4

Singleton. Cel: Przykład: Zastosowanie: Zapewnienie, że klasa ma tylko jedną instancję i dostarczenie globalnego dostępu do niej.

Oracle COREid Federation Przegląd

DHL24. Główny Użytkownik. i Przesyłka Serwisowa. Dokumentacja użytkownika końcowego

Dziedziczenie. Tomasz Borzyszkowski

KUP KSIĄŻKĘ NA: PRZYKŁADOWY ROZDZIAŁ KOMUNIKATY DLA UŻYTKOWNIKA

Plan. Wprowadzenie. Co to jest APEX? Wprowadzenie. Administracja obszarem roboczym

PORTAL KLIENTA I OBSŁUGA ZGŁOSZEŃ.V01. VULCAN Innowacji

Dokument Detaliczny Projektu

Webowy generator wykresów wykorzystujący program gnuplot

Szczegółowa specyfikacja funkcjonalności zamawianego oprogramowania.

Pomoc dla systemu WordPress

Skrócona instrukcja korzystania z Platformy Zdalnej Edukacji w Gliwickiej Wyższej Szkole Przedsiębiorczości

Programowanie obiektowe

ASP.NET MVC. Grzegorz Caban 20 stycznia 2009

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

Laboratorium 7 Blog: dodawanie i edycja wpisów

Wstęp [2/2] Wbrew częstemu przekonaniu, nie są one gotowymi rozwiązaniami, to tylko półprodukty rozwiązania.

Portal zarządzania Version 7.5

Diagram wdrożenia. Rys. 5.1 Diagram wdrożenia.

Certyfikat. 1 Jak zbieramy dane?

Wyjątki (exceptions)

Programowanie obiektowe - 1.

Web frameworks do budowy aplikacji zgodnych z J2EE

Programowanie w Sieci Internet Blok 2 - PHP. Kraków, 09 listopada 2012 mgr Piotr Rytko Wydział Matematyki i Informatyki

Programowanie Zespołowe

WINDOWS Instalacja serwera WWW na systemie Windows XP, 7, 8.

Dokument Detaliczny Projektu Temat: Księgarnia On-line Bukstor

Polityka prywatności

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

XQTav - reprezentacja diagramów przepływu prac w formacie SCUFL przy pomocy XQuery

System kontroli wersji - wprowadzenie. Rzeszów,2 XII 2010

Microsoft Class Server. Waldemar Pierścionek, DC EDUKACJA

Technologie Internetowe Raport z wykonanego projektu Temat: Internetowy sklep elektroniczny

Inżynieria oprogramowania II

Rozdział 5. Administracja kontami użytkowników

Programowanie obiektowe

E-commerce. Genialnie proste tworzenie serwisów w PHP i MySQL.

Programowanie obiektowe

Wzorce projektowe. dr inż. Marcin Pietroo

Diagram klas UML jest statycznym diagramem, przedstawiającym strukturę aplikacji bądź systemu w paradygmacie programowania obiektowego.

Wzorce projektowe. dr inż. Marcin Pietroo

Platforma e-learningowa

KATEDRA INFORMATYKI STOSOWANEJ PŁ INŻYNIERIA OPROGRAMOWANIA

Modele uwierzytelniania, autoryzacji i kontroli dostępu do systemów komputerowych.

2.5 Dzielenie się wiedzą

Badania poziomu bezpieczeństwa portalu dostępowego do infrastruktury projektu PL-Grid

UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami.

Rozwiązywanie problemów przekrojowych z użyciem IoC

Praca w sieci z serwerem

Analiza i projektowanie obiektowe 2016/2017. Wykład 8: Przypisywanie obiektom odpowiedzialności (2)

Programowanie obiektowe

System Kancelaris. Zdalny dostęp do danych

Generated by Foxit PDF Creator Foxit Software For evaluation only. System Szablonów

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Analiza i projektowanie obiektowe 2016/2017. Wykład 10: Tworzenie projektowego diagramu klas

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

Z pojedynczym obiekcie zasady grupy znajdziemy dwa główne typy ustawień:

System zarządzający grami programistycznymi Meridius

Transkrypt:

Bezpieczeństwo RBAC Kontrola dostępu w aplikacjach webowych Tworząc aplikacje webowe, szczególnie te bardziej skomplikowane, realizujące złożoną logikę biznesową, bardzo często spotykamy się z problemem kontroli dostępu. Każdy system, pracujący na danych o kluczowym znaczeniu, powinien mieć możliwość ograniczania dostępu do nich dla różnych użytkowników. Dowiesz się... Zaprezentujemy model RBAC i pokażemy, jak przy jego użyciu zaprojektować elastyczny i rozszerzalny moduł kontroli dostępu. Poziom trudności W artykule omówimy pokrótce teoretyczny model kontroli dostępu, opartej o role w konfrontacji z innymi powszechnie stosowanymi rozwiązaniami, a następnie zaproponujemy przykładową implementację kontroli dostępu w aplikacji webowej, stosującej wzorzec kontrolera strony. Problem Przy tworzeniu praktycznie każdej aplikacji, wykorzystywanej przez więcej niż jednego użytkownika, trzeba zmierzyć się z problemami kontroli dostępu. Jeden z nich to uwierzytelnianie, a więc weryfikacja tożsamości podmiotu. Drugi to autoryzacja, czyli sprawdzanie, czy dany podmiot ma dostęp do zasobów, o które prosi. W aplikacjach webowych uwierzytelnianie odbywa się na ogół poprzez podanie loginu i hasła. Implementacja ekranu logowania, to temat opisywany już wielokrotnie, więc na potrzeby tego tekstu założymy, że mechanizm uwierzytelniania jest już gotowy i skupimy się na bardziej złożonym problemie autoryzacji. Powszechną praktyką, stosowaną przez twórców aplikacji webowych (nawet jeśli nie są tego świadomi), jest zdefiniowanie trzech podstawowych poziomów dostępu: Anonimowy użytkownik to taki, który nie przeszedł procesu uwierzytelnienia. Powinieneś wiedzieć... Wskazana jest znajomość architektury MVC i wzorca dekoratora; Podstawowa wiedza z zakresu kontroli dostępu. Na ogół ma dostęp jedynie do ekranu logowania (system intranetowy) lub może korzystać z pewnych podstawowych funkcji (system internetowy); Zalogowany użytkownik to taki, który pomyślnie przeszedł proces uwierzytelnienia. Konta użytkowników są na ogół tworzone przez administratora (system intranetowy) lub ich samych, na przykład po weryfikacji mailowej (system internetowy); Administrator to specjalny użytkownik, który ma pełną kontrolę nad systemem. Często (choć nie zawsze) korzysta w tym celu z odrębnego panelu administratora. Takie rozwiązanie sprawdza się całkiem nieźle w prostych scenariuszach, gdy wszyscy użytkownicy są równorzędni, a administratorów jest niewielu i mają władzę absolutną. To założenie można śmiało przyjąć w przypadku wielu aplikacji internetowych, może stąd wynika jego powszechność. Jednak rzadko kiedy, tak prosty model okazuje się wystarczający dla intranetowych systemów o strategicznym znaczeniu, modelujących logikę biznesową firmy. W takiej sytuacji oczywiste jest, że szef powinien mieć inny poziom dostępu niż szeregowy pracownik, ten jeszcze inny niż podwykonawca, a dział techniczny inne uprawnienia niż dział obsługi klienta. Rozwiązanie, które często stosowane jest w takich sytuacjach, polega na sztywnym określeniu klas użytkowników, a następnie ograniczeniu dostępu do pewnych obszarów czy funkcji jedynie dla wybranych klas, poprzez zapisanie warunków bezpośrednio w kodzie. Na przykład w systemach śledzenia błędów często rozróżniani są zgłaszający (mogący tworzyć nowe zgłoszenia), programiści (mogący dodatkowo modyfikować stan zgłoszeń) i menedżerowie (mogący generować raporty i zestawienia). W przypadku systemu, w którym zadania są jasno zdefiniowane i niezmienne w czasie (jak wspomniany już system śledzenia błędów) takie rozwiązanie może się sprawdzić. Jednak zastosowanie tego podejścia w dużym systemie biznesowym, rozwijanym w warunkach ciągle zmieniających się wymagań, częstych reorganizacji i zmian strategii firmy ma liczne wady. Po pierwsze, cała logika kontroli dostępu zapisywana jest bezpośrednio w kodzie, jej modyfikacja wymaga ingerencji u źródła. Weryfikacja, dbanie o jej spójność i bezpieczeństwo jest mocno utrudnione. Co więcej, audyt wymaga wiedzy programistycznej i znajomości architektury systemu. Logika kontroli dostępu rozrzucona jest w różnych miejscach kodu, co utrudnia tworzenie nowych klas użytkowników czy implementację nowych modułów systemu, zwiększa też prawdopodobieństwo pomyłek. W końcu nie ma możliwości wdrożenia w oparciu o te same źródła kilku instancji systemu, z których każda ma inaczej zdefiniowaną logikę kontroli dostępu. Warto pamiętać także o tym, że każda zmiana w kodzie wymaga testów, co więcej, na serwerze produkcyjnym pojawi się nie od razu, a dopiero po wydaniu nowej wersji aplikacji. Jak widać, w takiej sytuacji cała odpowiedzialność za zarządzanie dostępem spada na programistów, podczas gdy powinna spoczy- Rysunek 1. Model RBAC 40 04/2007

RBAC wać na administratorze systemu, czy osobie odpowiedzialnej za bezpieczeństwo informacji w firmie. Takie rozwiązanie, choć często stosowane, narzuca wiele ograniczeń, które mogą okazać się nie do przyjęcia. W dalszej części artykułu zaproponujemy alternatywne rozwiązanie, dzięki któremu można uniknąć większości powyższych problemów. Opiszemy prosty, a zarazem bardzo elastyczny model RBAC i zaprezentujemy jego przykładową implementację. Model RBAC Kontrola dostępu oparta o role (ang. Role-Based Access Control, w skrócie RBAC), to teoretyczny model kontroli dostępu, od lat powszechnie stosowany w aplikacjach biznesowych, będący alternatywą dla tradycyjnych modeli MAC i DAC. Co ciekawe, formalizacji doczekał się dopiero w publikacji z roku 1992 (odnośnik do niej dostępny jest w materiałach do artykułu), gdy był już szeroko stosowany w praktyce. Podstawowym pojęciem w RBAC jest, jak łatwo się domyślić, rola, opisująca pewną funkcję czy stanowisko w organizacji. Kolejnym ważnym obiektem są uprawnienia, reprezentujące operacje udostępniane przez system. Uprawnienia przypisywane są do ról, określając tym samym ich prawa. Z kolei podmiotem określa się każdego użytkownika aplikacji, a także zewnętrzny system korzystający z jej usług. Podmiot może posiadać wiele ról, odpowiadających jego pozycji w strukturze organizacji. Zależności pomiędzy poszczególnymi pojęciami modelu RBAC ilustruje Rysunek 1. Niezwykle istotną własnością modelu RBAC jest to, że podmiot otrzymuje uprawnienia wyłącznie poprzez role, które posiada. Innymi słowy, z punktu widzenia kontroli dostępu, istotne jest jedynie stanowisko użytkownika, a nie jego tożsamość. Ta prosta własność sprawia, że struktura uprawnień staje się dużo bardziej przejrzysta i łatwiejsza w administracji. Warto zaznaczyć, że uprawnienia powinny opisywać operacje na poziomie logiki biznesowej, a nie prawa zapisu lub odczytu, do niskopoziomowych zasobów (jak pliki czy tabele w bazie danych). Innymi słowy zarówno role, jak i uprawnienia powinny być definiowane w języku konkretnej organizacji, na podstawie wcześniejszej analizy. Na koniec warto wspomnieć o pewnej bardzo dobrej praktyce kontroli dostępu, dotyczącej nie tylko modelu RBAC. Nazywana jest zasadą najmniejszych uprawnień (ang. Principle of Least Privilege) i mówi o tym, że użytkownik nie powinien posiadać większych uprawnień, niż to wymagane do wykonywania swoich obowiązków. Warto pamiętać o tym przy administracji uprawnieniami i rolami. Rysunek 2. Diagram przypadków użycia Rysunek 3. Diagram kontrolerów Przykład implementacji Omówiliśmy pokrótce podstawy teoretyczne, spróbujmy więc zaimplementować RBAC w przykładowej aplikacji webowej. Wyjdziemy od analizy przypadków użycia, która ułatwi określenie potrzebnych ról i uprawnień. Następnie, korzystając ze wzorca dekoratora (opisanego m.in. w artykule Dekorator: wzorzec projektowy na każdą bolączkę z numeru 4/2006, dostępnego do ściągnięcia na stronie PHP Solutions), zaprojektujemy i zaimplementujemy klasy, odpowiadające za kontrolę dostępu w przykładowej architekturze stosującej kontroler strony. Skupimy się na najbardziej interesujących z punktu widzenia niniejszego artykułu aspektach, nie zajmując się chociażby sposobem dostępu do bazy danych czy przebiegiem procesu logowania. Przykład celowo nie jest związany z żadnym konkretnym frameworkiem (choć opiera się na architekturze stosowanej w wielu z nich), aby pokazać ogólność rozwiązania. Przypadki użycia Rozważmy typowy system obsługi zgłoszeń (ang. trouble tickets), którego głównym zadaniem jest usprawnienie kontaktu z klientami. Po analizie dziedziny mógłby powstać diagram przypadków użycia taki, jak na Rysunku 2. (mocno uproszczony dla celów przykładu). Pomoże on nam zdefiniować role i uprawnienia. Jak wiadomo, role opisują funkcje, jakie w organizacji pełnią użytkownicy (mówiąc bar- www.phpsolmag.org 41

Bezpieczeństwo dziej ogólnie, podmioty). Jeśli korzystamy z diagramu przypadków użycia, dobrymi kandydatami na role są aktorzy (choć nie zawsze musi to być relacja jeden-na-jeden). W opisanym przykładzie możemy wyróżnić następujące role: Klient: osoba korzystająca z systemu, aby zgłosić swój problem i śledzić jego stan; Konsultant: pracownik odpowiadający za obsługę zgłoszeń klientów; Menedżer: osoba nadzorująca pracę konsultantów. Kolejnym krokiem jest określenie uprawnień, najmniejszego i niepodzielnego kwantu, umożliwiającego kontrolę dostępu w modelu RBAC. Role zawsze można zmienić, jednak odpowiedni dobór,,rozdzielczości uprawnień, to ważna decyzja projektowa. Od tego zależy, jak łatwe i elastyczne będzie definiowanie ról, i jak precyzyjna kontrola dostępu będzie możliwa. Także w tym przypadku można oprzeć się na przypadkach użycia, często jednak okazuje się, że uprawnienia powinny być nieco bardziej szczegółowe i niskopoziomowe. Wtedy jeden przypadek użycia można rozbić na kilka uprawnień. Implementacja kontroli dostępu staje się znacznie łatwiejsza, jeśli uprawnienia mają swoje odpowiedniki w samym systemie. Dlatego w przykładzie opisanym poniżej zastosujemy kontrolę uprawnień w warstwie kontrolera, a uprawnienia utożsamimy ze zdarzeniami kontrolera (a same kontrolery zaprojektujemy tak, aby ich zdarzenia odpowiadały uprawnieniom). Kontrolery Projektując architekturę aplikacji webowej, najprawdopodobniej skorzystamy z jakiegoś rodzaju kontrolera, obsługującego żądania HTTP. Jeśli wszystkie żądania przechodzą przez kontroler, wybór uprawnień i implementacja kontroli dostępu staje się prosta i przejrzysta. Załóżmy, że stosujemy wzorzec Page Controler (choć podobny sposób rozumowania można także zastosować dla Front Controllera), a każdy kontroler to osobny plik PHP, obsługujący żądanie dla danego URL. Dodatkowo zakładamy, że kontroler otrzymuje jako parametr żądania nazwę zdarzenia, które ma obsłużyć. Wszystkie kontrolery dziedziczą po wspólnej abstrakcyjnej nadklasie i implementują metody onaction(), gdzie action to nazwa zdarzenia, które obsługuje dana metoda. W uproszczonym przykładzie projektowanego systemu obsługi zgłoszeń, podstawowymi pojęciami są zgłoszenia i raporty, a więc to dla nich utworzymy kontrolery. Projektując zdarzenia najlepiej wyjść od przypadków użycia, choć często okazuje się, że zdarzenia powinny być bardziej szczegółowe. Dobrym przykładem są tu tzw. przypadki użycia CRUD (ang. Create, Read, Update, Delete), łączące operacje tworzenia obiektu, jego modyfikacji i usuwania (a więc trzech osobnych zdarzeń) w jeden przypadek użycia,,zarządzanie obiektem. Przykładowy diagram kontrolerów dla naszego systemu obsługi zgłoszeń znajduje się na Rysunku 3. Rysunek 4. Diagram dekoratorów kontrolera Rysunek 5. Diagram sekwencji kontroli dostępu 42 04/2007

Bezpieczeństwo Jak łatwo się już domyślić, w aplikacji webowej o takiej architekturze, dobrym kandydatem na uprawnienie (w rozumieniu modelu RBAC) będzie para $(kontroler, zdarzenie)$. Przemawia za tym kilka faktów: Kontrolę uprawnień możemy przeprowadzić na poziomie kontrolera, wtedy staje się ona przezroczysta dla programisty, co Listing 1. Dekorator kontrolera abstract class ControllerDecorator implements Controller protected $decoratedcontroller; function construct(controller $decoratedcontroller) $this->decoratedcontroller = $decoratedcontroller; function geteventname() return $this->decoratedcontroller->geteventname(); function getname() return $this->decoratedcontroller->getname(); function run() return $this->decoratedcontroller->run(); Listing 2. Dekorator kontroli dostępu class ControllerRbacDecorator extends ControllerDecorator private $profile; ułatwia pracę, ale także ogranicza możliwe dziury w bezpieczeństwie wynikające z przeoczeń; Taki wybór uprawnień sprawia, że mechanizm kontroli dostępu staje się rozszerzalny wraz z rozbudową systemu, a narzut związany z jego utrzymaniem i aktualizacją jest minimalny (nowe uprawnienia mogą być nawet rozpoznawane public function construct(controller $decoratedcontroller, Profile $profile) $this->profile = $profile; parent:: construct($decoratedcontroller); function run() if (!$this->profile->haspermission($this->getname(), $this->geteventname())) throw new Exception("Brak uprawnień"); return $this->decoratedcontroller->run(); automatycznie, za pomocą refleksji klas kontrolerów); Równoważność uprawnień i zdarzeń kontrolera ułatwia komunikację w zespole, nie ma potrzeby tworzenia i dokumentowania nowego pojęcia. Sprawę dodatkowo ułatwia fakt, że oba pochodzą od przypadków użycia, a te bezpośrednio powiązane są z aktorami (a więc i rolami). Tabela 1. zawiera podsumowanie przypadków użycia, odpowiadających im zdarzeń i uprawnień w projektowanym przez nas systemie. W dalszej części artykułu zaproponujemy implementację przezroczystej dla kontrolera kontroli dostępu, przy założeniu, że uprawnieniami są zdarzenia kontrolera. Dekorowanie kontrolera Skoro uprawnienia są jednoznaczne z prawami dostępu do zdarzeń kontrolera, a każde żądanie musi przejść przez kontroler, dobrym miejscem na implementację kontroli dostępu jest właśnie klasa kontrolera. Oczywiście można zapisać odpowiednie warunki w kodzie nadklasy, po której dziedziczą kontrolery (albo utworzyć klasę po niej dziedziczącą), jednak nie jest to zbyt eleganckie rozwiązanie. Obsługa żądań i kontrola dostępu to dwa różne zadania, które nie powinny być łączone. W takich sytuacjach dobrym pomysłem jest skorzystanie z wzorca dekoratora, który pozwala na dynamiczne zwiększanie zakresu odpowiedzialności obiektu. Rysunek 4. zawiera zmodyfikowany schemat klas kontrolerów, rozbudowany o abstrakcyjny dekorator i dziedziczący po nim dekorator przeprowadzający kontrolę uprawnień. Na Listingu 1. znajduje się kod dekoratora, realizującego interfejs kontrolera, który w konstruktorze otrzymuje obiekt do udekorowania i przekierowuje do niego wszystkie metody interfejsu. Warto zauważyć, że klasa jest zdefiniowana jako abstrakcyjna mimo, że nie posiada żadnych abstrakcyjnych metod. Po prostu tworzenie obiektów tej klasy nie ma żadnego sensu, istnieje tylko po to, aby konkretne dekoratory dziedziczące po niej, nie musiały za każdym razem implementować mechanizmu dekoracji. Na Listingu 2. znajduje się kod dekoratora przeprowadzającego kontrolę dostępu przed przekazaniem sterowania do metody realizującej zdarzenie. Zakładamy, że w konstruktorze został przekazany profil opisujący aktualnie zalogowanego użytkownika. Metoda haspermission() profilu sprawdza (przeglądając wszystkie role), czy użytkownik ma uprawnienia do danego kontrolera i zdarzenia. Jeśli nie, dekorator wyrzuca wyjątek i nie 44 04/2007

RBAC W Sieci David Ferraiolo, Richard Kuhn. Role-Based Access Control, http://csrc.nist.gov/rbac/ Role_Based_Access_Control-1992.html; Wikipedia: Role-Based Access Control, http://en.wikipedia.org/wiki/role-based_access_control. Tabela 1. Związek przypadków użycia, metod kontrolera i uprawnień Przypadek użycia Metoda kontrolera Uprawnienie Utworzenie zgłoszenia TicketsController::onCreate() (tickets, create) Podgląd zgłoszenia TicketsController::onView() (tickets, view) Zamknięcie zgłoszenia TicketsController::onClose() (tickets, close) Dodanie komentarza TicketsController::onComment() (tickets, comment) Generowanie raportu ReportsController::onGenerate() (reports, generate) przekazuje sterowania do dekorowanego kontrolera. Utworzenie i wywołanie udekorowanego kontrolera przebiega w następujący sposób (zakładając, że mamy referencję do profilu użytkownika): $controller = new ControllerRbacDe try $controller->run(); catch (Exception $e) corator(new TicketsController(), $profile); echo "Błąd: ". $e->getmessage(); Nie są wymagane żadne zmiany w samych klasach kontrolera, za kontrolę dostępu odpowiada tylko dekorator. Jak to działa Na koniec warto przeanalizować diagram sekwencji przedstawiony na Rysunku 5., przedstawiający dynamiczny obraz procesu kontroli dostępu. Przeglądarka użytkownika wysyła żądanie HTTP, które serwer kieruje do odpowiedniego kontrolera, wywoływana jest jego metoda run(). Kontroler został udekorowany, więc dekorator najpierw pobiera nazwę dekorowanego kontrolera oraz zdarzenia, które zostało wywołane przez użytkownika. Następnie profil proszony jest o sprawdzenie, czy aktualnie zalogowany użytkownik ma uprawnienia do danego kontrolera i zdarzenia (i czy jest w ogóle zalogowany). To, jak działa i kiedy tworzony jest profil, nie wchodzi w zakres niniejszego artykułu. Warto jednak wspomnieć, że profil powinien obsługiwać logowanie, wylogowanie i przechowywanie informacji o użytkowniku w sesji, a także powinien przekierowywać niezalogowanego użytkownika do kontrolera logowania (który oczywiście nie może być dekorowany kontrolą dostępu). Profil, sprawdzając uprawnienia, powinien opierać się na liście ról bieżącego użytkownika. Jeśli posiada on dane uprawnienie, kontrola przekazywana jest do udekorowanego kontrolera, który z kolei wywołuje metodę obsługującą dane zdarzenie. Jeśli nie, wyrzucany jest wyjątek, który oczywiście powinien zostać odpowiednio obsłużony. Jak widać dzięki założeniu, że wszystkie żądania muszą przejść przez kontroler i dzięki użyciu wzorca dekoratora, udało się w prosty sposób zaimplementować przezroczysty dla programisty i rozszerzalny moduł kontroli dostępu. Dzięki zastosowaniu modelu RBAC logika kontroli dostępu nie jest zapisana bezpośrednio w kodzie, a w dynamicznych zależnościach między podmiotami, rolami i uprawnieniami. Dzięki temu cała struktura jest bardzo przejrzysta, łatwa w administracji i może być modyfikowana przez osoby nie będące programistami. Co więcej, polityka bezpieczeństwa może różnić się między kilkoma instalacjami systemu. Możliwe ulepszenia Zaprezentowany powyżej szkic implementacji nie jest jedynym możliwym, można go rozwinąć i ulepszyć na wiele sposobów, oto kilka z nich: Przydatny będzie panel administracyjny, pozwalający na zarządzanie rolami, przypisywanie uprawnień do ról i ról do użytkowników. Oczywiście dostęp do takiego modułu także można, i należy chronić za pomocą opisanego mechanizmu kontroli dostępu; Główną wadą kontroli dostępu na poziomie kontrolera jest to, że jest ściśle związana z żądaniami HTTP i warstwą kontrolera. Jeśli system posiada bogaty model domeny, wykorzystywany przez więcej niż jedną aplikację, warto rozważyć kontrolę dostępu w warstwie domeny. W takiej sytuacji teoretyczne podstawy pozostają bez zmian, ale zmienia się znaczenie uprawnień i implementacja kontroli dostępu; Można zmodyfikować szablony tak, aby deaktywować czy nawet usuwać odnośniki do operacji, do których bieżący użytkownik nie ma dostępu; Łatwo napisać skrypt, który automatycznie zaktualizuje tabelę uprawnień na podstawie analizy kodu kontrolerów. Dzięki temu nie trzeba pamiętać o uzupełnianiu tabeli uprawnień w bazie wraz z rozwojem systemu. Taki skrypt może po prostu szukać w plikach źródłowych wzorców, odpowiadających metodom kontrolera (np. przy użyciu wyrażeń regularnych), albo wykorzystać mechanizm refleksji. Na podstawie zebranych danych można synchronizować tabelę uprawnień. W bardziej skomplikowanych projektach można rozważyć zastosowanie bardziej zaawansowanych aspektów modelu RBAC: Nietrudno dodać, bardzo przydatny w praktyce, mechanizm dziedziczenia uprawnień. Dzięki temu menedżer będzie mógł dziedziczyć z roli konsultanta, przejmując wszystkie uprawnienia roli dziedziczonej i uzupełniając je o uprawnienia specyficzne dla roli dziedziczącej (podobnie do mechanizmu dziedziczenia w programowaniu obiektowym); Założyliśmy, że użytkownik po zalogowaniu może korzystać ze wszystkich swoich ról i związanych z nimi uprawnień. Alternatywnym i bardziej zgodnym z modelem RBAC rozwiązaniem jest wymuszenie wyboru jednej z dostępnych ról w momencie logowania. Wtedy powstaje sesja, łącząca użytkownika z aktywną rolą (nie mylić z mechanizmem sesji PHP); Można zaimplementować politykę separacji obowiązków (ang. Separation of Duties), mającą na celu ograniczenie zagrożeń wynikających z łączenia kilku ról przez jednego pracownika. Ta zasada mówi, że dla pewnego zbioru operacji (np. zlecenia przelewu i akceptacji przelewu) nie może istnieć osoba, która ma uprawnienia do wszystkich z nich. Zachęcamy Czytelników do dalszych eksperymentów i dzielenia się swoimi pomysłami. Podsumowanie Stosując sprawdzony model kontroli dostępu opartej o role, udało nam się w łatwy sposób zaprojektować prosty, elegancki i elastyczny mechanizm kontroli dostępu. Uniknęliśmy zaszywania kontroli dostępu bezpośrednio w kodzie, pozwalając na dynamiczne przydzielanie uprawnień do ról, a zarazem ułatwiając administrację uprawnieniami. ADAM BYRTEK Autor odpowiada za zespół programistyczny, zajmujący się rozwojem wewnętrznego systemu OSS/BSS dla ogólnopolskiego dostawcy internetu. Kontakt z autorem: adambyrtek@gmail.com http://adambyrtek.blogspot.com/ www.phpsolmag.org 45