Model roli dla struktury wielu usług: od walidacji według ról do siatki dostępu
W projekcie wieloserwisowym autoryzacja była oparta na rolach użytkowników. Wraz ze wzrostem ich liczby przeszliśmy na model oparty na uprawnieniach. Użytkownik ma rolę i przynależność do organizacji, a rola określa domyślny zestaw uprawnień. Każda organizacja może otrzymać dodatkowe, niestandardowe uprawnienia. Stworzyliśmy też interfejs, który pozwala zespołom biznesowym samodzielnie zarządzać rolami i uprawnieniami, przeglądać historię zmian oraz je wycofywać.
Problem: Przybywało ról, a zarządzanie dostępami stawało się coraz bardziej skomplikowane
W ramach projektu odpowiadaliśmy za uwierzytelnianie, usługę wysyłkową i kilka innych serwisów. Nasi koledzy odpowiadali natomiast za wewnętrzne serwisy oparte na platformie 1C-Bitrix. Dostęp do każdego serwisu był ograniczany na podstawie roli użytkownika.
Jak to wyglądało w praktyce:
-
Administratorzy po zalogowaniu widzieli przypisane im serwisy.
-
Klienci — swoje serwisy publiczne.
-
Pracownicy wsparcia — swoje.
Początkowo wszystko działało dobrze. Jednak liczba ról stale rosła. Pojawiały się nowe serwisy, nowe scenariusze użycia i nowe typy użytkowników. Każda nowa rola wymagała ponownego określenia, do czego ma mieć dostęp, a do czego nie.
Sprawdzanie uprawnień bezpośrednio na podstawie roli stało się wąskim gardłem. Postanowiliśmy wdrożyć macierz uprawnień: zamiast sprawdzać samą rolę, system miał weryfikować uprawnienia przypisane do tej roli.
Pierwsza iteracja: rola + organizacja + uprawnienia
Zaprojektowaliśmy model, w którym:
-
Użytkownik ma przypisaną rolę oraz przynależność do organizacji.
-
Rola ma domyślny zestaw uprawnień — obejmujący dostęp do serwisów, dostępne metody uwierzytelniania (dwuskładnikowe, jednoskładnikowe, SMS, wyłącznie numer telefonu i kod oraz kombinacje różnych metod), a także dostęp do poszczególnych modułów funkcjonalnych.
-
Dla każdej organizacji i roli można skonfigurować niestandardowe uprawnienia.
Co nam to dało?
Użytkownik z rolą „Manager” w organizacji A mógł mieć jeden zestaw uprawnień. Inny użytkownik z tą samą rolą w organizacji B — inny. Trzeci, w organizacji C — jeszcze inny.
Rola przestała być sztywnym ograniczeniem. Stała się szablonem, który można dostosować do potrzeb konkretnej organizacji.
Jak to działało: pełny proces uwierzytelniania
Prześledźmy drogę użytkownika — od formularza logowania aż do uzyskania dostępu do serwisu.
1. Wybór metody uwierzytelniania
Na ekranie logowania użytkownik wybiera jedną z metod: adres e-mail i hasło albo numer telefonu i kod SMS.
2. Wypełnienie formularza
Użytkownik wprowadza dane odpowiednie dla wybranej metody uwierzytelniania.
3. Weryfikacja po stronie backendu
Żądanie trafia do backendu. System sprawdza, czy użytkownik istnieje, wyszukując go po numerze telefonu lub adresie e-mail — w zależności od wprowadzonych danych.
4. Jeśli użytkownik nie zostanie znaleziony
System wyświetla komunikat:
„Użytkownik o podanych danych nie istnieje. Sprawdź dane lub zarejestruj się”.
5. Jeśli użytkownik zostanie znaleziony
Sprawdzamy, które metody uwierzytelniania są dostępne dla jego roli. Jeśli wybrana metoda nie jest dozwolona, system wyświetla komunikat z prośbą o skorzystanie z jednej z dostępnych metod. Następnie proces przebiega zgodnie z konfiguracją roli użytkownika.
6. Menu wyboru serwisów
Po uwierzytelnieniu użytkownik trafia do menu wyboru serwisów.
-
Jeśli należy do kategorii pracowników wewnętrznych, ma dostęp do dwóch kategorii serwisów: przeznaczonych dla użytkowników wewnętrznych oraz dla użytkowników zewnętrznych. W przeciwnym razie widzi wyłącznie serwisy przeznaczone dla użytkowników zewnętrznych.
-
Lista serwisów jest generowana na podstawie uprawnień przypisanych do roli. Serwisy, do których użytkownik nie ma dostępu, nie są wyświetlane.
7. Uwierzytelnianie w serwisie za pomocą OAuth 2.0
Po wybraniu serwisu uwierzytelniamy użytkownika za pomocą OAuth 2.0. Po zakończeniu uzgadniania komunikacji między systemami serwis docelowy wysyła zapytanie o aktualne uprawnienia użytkownika. Nasz system zwraca odpowiedni zestaw uprawnień za pośrednictwem API w formacie JSON.
Po zakończeniu uwierzytelniania serwis docelowy zapisuje zestaw uprawnień w sesji użytkownika.
8. Korzystanie z serwisu
Użytkownik może teraz korzystać z serwisu w zakresie wynikającym z przypisanych mu uprawnień.
9. Użytkownicy API
Użytkownicy API również mają przypisane uprawnienia — zgodnie z tym samym modelem.
Rozwój systemu: model ról przestał wystarczać
Wraz z rozwojem systemu musieliśmy rozbudowywać również sam model ról.
Jak to wyglądało w praktyce:
-
Na początku model ról był zamknięty — zestaw ról i uprawnień był z góry określony.
-
Z czasem biznes zaczął regularnie zgłaszać potrzebę dodawania nowych ról i uprawnień za pośrednictwem zespołu deweloperskiego.
-
Pojawiły się również prośby o zmianę zestawu uprawnień dla konkretnej organizacji, do której przypisana była dana rola.
Każda taka zmiana wymagała utworzenia zadania dla zespołu deweloperskiego. Biznes musiał czekać, a zespół poświęcał czas na powtarzalne, rutynowe modyfikacje.
Rozwiązanie: interfejs do zarządzania modelem ról
Zaproponowaliśmy biznesowi interfejs umożliwiający samodzielne zarządzanie modelem ról. Pomysł został zaakceptowany.
Stworzyliśmy odpowiedni interfejs w aplikacji do zarządzania użytkownikami i systemami, wykorzystując stos technologiczny Laravel + Vue.js.
Co można było zrobić za pomocą interfejsu:
-
Tworzyć grupy ról i dodawać poszczególne role.
-
Przypisywać każdej roli nazwę w alfabecie łacińskim oraz nazwę cyrylicą.
-
Określać, czy dana rola jest wewnętrzna, czy zewnętrzna.
-
Tworzyć grupy uprawnień i dodawać poszczególne uprawnienia.
-
Przypisywać każdemu uprawnieniu nazwę w alfabecie łacińskim oraz nazwę cyrylicą.
-
Wykorzystywać nazwy uprawnień zapisane alfabetem łacińskim jako identyfikatory uprawnień w systemach.
Historia zmian i przywracanie poprzedniej konfiguracji
Wdrożyliśmy funkcjonalność historii zmian modelu ról. W razie problemów lub konieczności przywrócenia wcześniejszej konfiguracji można było cofnąć się do dowolnego poprzedniego stanu.
Główny element: macierz uprawnień
Kluczowym elementem interfejsu była macierz uprawnień, serwisów i ról, w której można było określić, czy dany dostęp ma być dozwolony, czy zabroniony.
Podobna macierz była dostępna podczas edycji każdej organizacji, co pozwalało zarządzać jej rolami oraz przypisanymi do nich uprawnieniami.
Dzięki temu biznes zyskał samodzielność i mógł modyfikować model ról bez angażowania zespołu deweloperskiego.
Rezultat: elastyczny model i narzędzie do zarządzania
Nie tylko opracowaliśmy elastyczny model ról dopasowany do potrzeb biznesowych, ale także stworzyliśmy interfejs umożliwiający zarządzanie tym modelem.
Stos technologiczny
-
Backend: Laravel (PHP)
-
Frontend: Vue.js
-
Uwierzytelnianie: OAuth 2.0
-
Wymiana danych: API, JSON
Czego nauczyliśmy się dzięki temu projektowi?
1. Kontrola dostępu oparta wyłącznie na rolach nie skaluje się
Gdy liczba ról rośnie, bezpośrednie sprawdzanie dostępu na podstawie roli staje się trudne do utrzymania i prowadzi do chaosu. Kontrola dostępu oparta na uprawnieniach jest bardziej elastycznym i przewidywalnym rozwiązaniem.
2. Kontekst ma znaczenie: ta sama rola może oznaczać różne uprawnienia
Użytkownicy z tą samą rolą mogą mieć różne uprawnienia w zależności od organizacji. To typowa sytuacja w systemach B2B, którą model dostępu powinien uwzględniać.
3. Biznes potrzebuje narzędzi, a nie kolejki zgłoszeń do deweloperów
Jeśli biznes regularnie prosi o zmiany ról i uprawnień, warto udostępnić mu interfejs do samodzielnego zarządzania nimi. Pozwala to odciążyć zespół i przyspieszyć realizację potrzeb biznesowych.
4. Historia zmian jest niezbędna
Model ról stanowi krytyczny element systemu. Możliwość przywrócenia poprzedniego stanu zabezpiecza przed skutkami błędów konfiguracyjnych.
Podsumowanie
To historia o tym, jak system przerósł swój pierwotny model dostępu i jak zamiast bez końca łatać istniejące rozwiązanie, przebudowaliśmy całe podejście: od kontroli dostępu opartej na rolach do macierzy uprawnień oraz od ręcznych zmian do dedykowanego interfejsu zarządzania.
Elastyczny model uprawnień + narzędzie do zarządzania = system, który rozwija się razem z biznesem.