System autoryzacji i uwierzytelniania dla mikrousług i konsumentów

15

Planujemy przekształcić system naszej firmy w system oparty na mikrousługach. Z tych mikro-usług będą korzystać nasze własne wewnętrzne aplikacje firmy oraz w razie potrzeby partnerzy zewnętrzni. Jeden do rezerwacji, drugi do produktów itp.

Nie jesteśmy pewni, jak radzić sobie z rolami i zakresami. Chodzi o to, aby utworzyć 3 podstawowe role użytkowników, takie jak administratorzy, agenci i użytkownicy końcowi, i pozwolić aplikacjom konsumenckim na dostosowanie zakresów w razie potrzeby.

  • Administratorzy mogą domyślnie tworzyć, aktualizować, czytać i usuwać wszystkie zasoby (dla swojej firmy).
  • Agenci mogą tworzyć, aktualizować i odczytywać dane swojej firmy.
  • Użytkownicy końcowi mogą tworzyć, aktualizować, usuwać i odczytywać dane, ale nie mają dostępu do tych samych punktów końcowych co agenci lub administratorzy. Będą także mogli tworzyć lub modyfikować dane, ale nie na tym samym poziomie co agenci lub administratorzy. Na przykład użytkownicy końcowi mogą aktualizować lub czytać informacje o swoim koncie, tak samo jak agent będzie mógł to dla nich zrobić, ale nie widzą ani nie aktualizują notatek administratora.

Powiedzmy, że agenci domyślnie mogą tworzyć, odczytywać i aktualizować każdy zasób dla swojej firmy i to jest ich maksymalny zakres, którego można żądać dla tokena / sesji, ale programiści aplikacji klienckiej (API-konsument) zdecydowali, że jeden z ich agentów może czytaj i twórz tylko niektóre zasoby.

Czy lepiej jest radzić sobie z tym w naszym wewnętrznym bezpieczeństwie i pozwolić im zapisywać te dane w naszej bazie danych, czy pozwolić klientom obsługiwać to wewnętrznie, żądając tokena o mniejszym zakresie, i pozwól im napisać, który agent będzie miał zakres w swojej bazie danych ? W ten sposób musielibyśmy śledzić tylko zakresy tokena.

Wadą tego jest to, że nasz zespół musiałby również stworzyć mechanizmy dostępu dostosowane do naszych wewnętrznych aplikacji.

Przy takim sposobie myślenia, mikrousługom i ich systemowi autoryzacji nie należy przejmować się potrzebami klientów, ponieważ są oni tylko konsumentami, a nie częścią systemu (nawet jeśli niektórzy z tych konsumentów są naszymi wewnętrznymi aplikacjami)?

Czy ta delegacja jest dobrym podejściem?

Robert
źródło

Odpowiedzi:

14

Uwierzytelnianie i autoryzacja to zawsze dobre tematy

Spróbuję wyjaśnić, w jaki sposób radzimy sobie z autoryzacjami w bieżącej usłudze dla wielu dzierżawców, którą pracuję. Uwierzytelnianie i autoryzacja są oparte na tokenach, przy użyciu otwartego standardu tokenu internetowego JSON. Usługa udostępnia interfejs API REST, do którego może uzyskać dostęp dowolny klient (aplikacje internetowe, mobilne i stacjonarne). Po pomyślnym uwierzytelnieniu użytkownika usługa udostępnia token dostępu, który należy wysłać przy każdym żądaniu do serwera.

Pozwólcie, że przedstawię kilka używanych przez nas pojęć w oparciu o to, jak postrzegamy i traktujemy dane w aplikacji serwera.

Zasób : dowolna jednostka lub grupa danych, do których klient może uzyskać dostęp za pośrednictwem usługi. Do wszystkich zasobów, które chcemy kontrolować, przypisujemy jedną nazwę. Na przykład, mając kolejne reguły punktu końcowego, możemy nazwać je w następujący sposób:

product

/products
/products/:id

payment

/payments/
/payments/:id

order

/orders
/orders/:id
/orders/:id/products
/orders/:id/products/:id

Powiedzmy, że do tej pory mamy do dyspozycji trzy zasoby ; product, paymentI order.

Działanie : Jest to operacja, którą można wykonać na zasobie, takim jak, czytać, tworzyć, aktualizować, usuwać itp. Nie musi to być zwykłe klasyczne operacje CRUD, możesz mieć akcję o nazwie follownp. chcesz udostępnić usługę, która propaguje pewne informacje za pomocą WebSockets.

Umiejętność : Umiejętność wykonania actionna resource. Na przykład; czytaj produkty, twórz produkty itp. Jest to po prostu para zasobów / akcji. Możesz jednak dodać do niego także nazwę i opis.

Rola : zestaw umiejętności, które użytkownik może posiadać. Na przykład rola Cashiermoże mieć możliwości „odczytu płatności”, „utworzenia płatności” lub rola Sellermoże mieć zdolności „odczytu produktu”, „kolejności odczytu”, „kolejności aktualizacji”, „kolejności usuwania”.

Wreszcie użytkownik może przypisać mu różne role.


Wyjaśnienie

Jak powiedziałem wcześniej, używamy JSON Web Token, a umiejętności, które użytkownik posiada, są zadeklarowane w ładunku tokena. Załóżmy zatem, że mamy użytkownika z rolą kasjera i sprzedawcy jednocześnie dla małego sklepu detalicznego. Ładunek będzie wyglądał następująco:

{
    "scopes": {
        "payment": ["read", "create"],
        "order": ["read", "create", "update", "delete"]
    }
}

Jak widać w scopesroszczeniu, nie podajemy nazw ról (kasjer, sprzedawca), a jedynie zasoby i działania, które są implikowane. Gdy klient wysyła żądanie do punktu końcowego, usługa powinna sprawdzić, czy token dostępu zawiera wymagane zasoby i działania. Na przykład GETżądanie do punktu końcowego /payments/88zakończy się powodzeniem, ale DELETEżądanie do tego samego punktu końcowego musi zakończyć się niepowodzeniem.


  • Jak pogrupować i nazwać zasoby oraz jak zdefiniować i nazwać działania i zdolności, będą decyzją deweloperów.

  • Jakie role i jakie zdolności będą miały te role, to decyzje podejmowane przez klientów.


Oczywiście należy dodać dodatkowe właściwości do ładunku, aby zidentyfikować użytkownika i klienta (najemcę), który wydał token.

{
    "scopes": {
        ...
    },
    "tenant": "acme",
    "user":"coyote"
}

Dzięki tej metodzie możesz precyzyjnie dostroić dostęp dowolnego konta użytkownika do usługi. A co najważniejsze, nie musisz tworzyć różnych predefiniowanych i statycznych ról, takich jak administrator, agenci i użytkownicy końcowi, jak wskazano w pytaniu. Super Użytkownik będzie użytkownik, który jest właścicielem roleze wszystkimi resourcesi actionsusługi przypisanej do niego.

Co teraz, jeśli jest 100 zasobów i chcemy roli, która daje dostęp do wszystkich lub prawie wszystkich? Nasz ładunek tokena byłby ogromny. Można to rozwiązać poprzez zagnieżdżenie zasobów i dodanie zasobu nadrzędnego do zakresu tokena dostępu.


Autoryzacja to skomplikowany temat, którym należy się zająć w zależności od potrzeb każdej aplikacji.

miso
źródło
Dziękuję za odpowiedź. To jest bardzo pomocne. Mam pytanie związane z wieloma rolami na użytkownika. Czy zdarzyło Ci się kiedyś, że uprawnienia do roli nakładają się na siebie? Tak jak kasjer payment:[read], sprzedawca ma payment: [create]. Czy agregujesz uprawnienia w tym przypadku?
Robert,
Jeśli masz role z powtarzającymi się zdolnościami (resource/action), musisz je połączyć. Jeśli uprawnienia się pokrywają, należy je agregować. Chodzi o to, aby zdefiniować tylko zasoby i działania dozwolone w tokenie, pozostawiając role jako abstrakcję używaną, aby dać klientom mniej skomplikowany sposób radzenia sobie z autoryzacją.
miso
1
co jeśli użytkownik może mieć możliwość podjęcia działań tylko w stosunku do zasobów, których jest właścicielem. Podobnie jak na przykład konto bankowe, na pewno „bank_account”: [„read”, „update”] tego nie określa. Również dokładnie GDZIE proces autoryzacji odbywa się w systemie Microservices? Na scentralizowanym serwerze autoryzacyjnym, czy każda usługa ma własną autoryzację?
rakietowiec
@rocketspacer. Dlatego token ma userwłaściwość w swoim ładunku. Sposób, w jaki blokuję zasób będący własnością użytkownika, polega na mapowaniu userroszczenia na adres URL. Na przykład: /users/coyote/back-accountbyłby dostępny tylko przez token z userroszczeniem równym coyote. Mam nadzieję, że ta pomoc.
miso,
3

Myślę, że bez względu na wszystko, chcesz, aby twoje usługi akceptowały token uwierzytelniania, który jest zapewniany przez usługę uwierzytelniania, którą piszesz w celu weryfikacji użytkowników. Jest to najprostszy / bezpieczny sposób, aby zapobiec niewłaściwemu użyciu mikrousług. Ponadto, ogólnie rzecz biorąc, jeśli chcesz, aby klient miał dobre doświadczenia, powinieneś samodzielnie wdrożyć najważniejsze funkcje i dokładnie przetestować, aby upewnić się, że oferowane funkcje są dobrze wdrożone.

Ponieważ wszyscy dzwoniący muszą przedstawić mikrousługom dowód, że zostali uwierzytelnieni, równie dobrze możesz powiązać uprawnienia z tym uwierzytelnieniem. Jeśli zapewnisz możliwość powiązania użytkownika z dowolną grupą dostępu (lub grupami, jeśli chcesz się podoba, chociaż trudniej jest tutaj poradzić sobie z dodawaniem i odejmowaniem uprawnień). Od twoich klientów będzie mniej pytań o to, dlaczego użytkownik x był w stanie wykonać niepożądaną operację. W każdym razie ktoś musi sprawdzić listę dostępu dla każdej usługi, więc równie dobrze może to być Ty. Jest to coś, co bardzo łatwo byłoby zakodować na początku wszystkich usług (if ( !TokenAuthorized(this.ServiceName, this.token) { Raise error }) Abyś mógł to zrobić i samemu śledzić grupy użytkowników. To prawda, że ​​będziesz musiał mieć menedżera grupy uprawnień i pracować z nim w interfejsie zarządzania użytkownikami (użyj istniejącej / utwórz nową grupę dla uprawnień użytkowników) Zdecydowanie wyświetl listę użytkowników powiązanych z grupą podczas edycji definicji, aby uniknąć nieporozumień . Ale to nie jest trudna praca. Wystarczy mieć metadane dla wszystkich usług i powiązać wyszukiwanie mapowania między grupą a usługą w obsłudze tokenu uwierzytelniającego.

Ok, więc jest kilka szczegółów, ale każdy z klientów, którzy chcą tej funkcji, musiałby ją w każdym razie zakodować, a jeśli popierasz trzypoziomowe uprawnienia użytkownika, możesz po prostu rozszerzyć ją na dostęp dla poszczególnych użytkowników grupy. Prawdopodobnie logicznym skrzyżowaniem między uprawnieniami grupy podstawowej a uprawnieniami specyficznymi dla użytkownika byłaby właściwa agregacja, ale jeśli chcesz mieć możliwość dodawania i odbierania podstawowych uprawnień administratora, agenta, podstawowych uprawnień użytkownika, musisz to zrobić użytkowa trójstanowa flaga w grupach uprawnień: Dodaj zezwolenie, Odmów zezwolenia, Domyślne zezwolenie i odpowiednio łącz uprawnienia.

(Uwaga: to wszystko powinno się zdarzyć w przypadku czegoś takiego jak SSL lub nawet dwukierunkowy SSL, jeśli obawiasz się o bezpieczeństwo obu końców rozmowy. Jeśli „wyciekniesz” te tokeny do atakującego, jest on jakby „ d złamał hasło).

BenPen
źródło
Myśląc o infrastrukturze i wdrożeniu, zupełnie zapomniałem o doświadczeniu klienta. Podoba mi się pomysł stworzenia zestawu reguł, które będą bardziej związane z naszą działalnością. Administratorzy, agenci i użytkownicy końcowi są zbyt ogólni i planujemy wprowadzić więcej typów użytkowników, które są bardziej opisowe i powiązane z naszą działalnością i wszechobecnym językiem.
Robert,
Nie mogłem poprawić literówki „anded” w ostatnim zdaniu, ponieważ nie mogłem tego rozgryźć.
Tulains Córdova
To niekoniecznie literówka, ale ja to
wyjaśnię
1

Moim zdaniem masz tutaj dwie możliwości.

  • Jeśli potrzebujesz tylko konfigurowalnego dostępu do zasadniczo tej samej aplikacji, to masz uprawnienia do sprawdzania usług i daj swoim klientom interfejs, który pozwala im zmieniać uprawnienia nadawane każdej roli. Dzięki temu większość użytkowników może korzystać z domyślnej konfiguracji ról, którą „problematyczni” klienci mogą modyfikować role lub tworzyć nowe w zależności od potrzeb.

  • Jeśli Twoi klienci opracowują własne aplikacje, powinni wprowadzić własne pośrednie API. Która łączy się z Twoją administracją, ale sprawdza połączenia przychodzące z własnymi niestandardowymi wymaganiami uwierzytelniania przed wywołaniem twoich usług

Ewan
źródło
1

Względy bezpieczeństwa

Jeśli dobrze rozumiem twój projekt, zamierzasz przekazać niektóre mechanizmy kontroli dostępu do zasobów po stronie klienta, tj. Aplikacja konsumująca zmniejsza liczbę elementów, które użytkownik może zobaczyć. Twoje założenie jest następujące:

mikrousługom i ich systemowi autoryzacji nie należy przejmować się potrzebami klientów, ponieważ są oni tylko konsumentami, a nie częścią systemu

Widzę tutaj dwa poważne problemy dla poważnego biznesu:

  • Co się stanie, jeśli jakiś nieuczciwy użytkownik (na przykład w jednym z zakładów twojego partnera) dokona inżynierii wstecznej aplikacji klienckiej i dowie się o interfejsie API, obejdzie ograniczenia, które jego firma nałożyła na klienta i wykorzysta te informacje, aby zaszkodzić Twojej firmie? Twoja firma będzie dochodzić roszczeń odszkodowawczych, ale firma współpracująca będzie argumentować, że nie dałeś środków do wystarczającej ochrony swoich danych.
  • Zwykle jest to tylko kwestia czasu, w którym wrażliwe dane są niewłaściwie wykorzystywane (lub audyt wykryje ryzyko), a twoje kierownictwo ostatecznie poprosi o ściślejszą kontrolę tych danych.

Dlatego radzę przewidywać takie zdarzenia i zajmować się wnioskami o autoryzację. Jesteś na wczesnym etapie przebudowy i o wiele łatwiej będzie je uwzględnić w swojej architekturze (nawet jeśli nie zaimplementujesz ich wszystkich) niż później.

Jeśli kontynuujesz swoje obecne stanowisko, skonsultuj się przynajmniej z inspektorem bezpieczeństwa informacji.

Jak to wdrożyć

Masz sztuczkę:

W ten sposób musielibyśmy śledzić tylko zakresy tokena.

Ok, zamierzasz użyć niektórych ogólnych tokenów wybranych przez klienta. Znów słabość w moim oku, ponieważ niektórzy klienci mogą wymknąć się spod kontroli.

Nie wiem, czy już używasz JWT, czy używasz innych technik. Ale jeśli używasz JWT, możesz mieć token tożsamości, który przenosi tożsamość użytkownika (a nawet drugi token, który bezpiecznie identyfikuje aplikację źródłową, co może pozwolić ci na rozróżnienie poziomu zaufania między klientami wewnętrznymi a klientami zewnętrznymi ).

Jeśli zamierzasz wybrać architekturę mikrousług, chciałbym zasugerować różnicę między zarządzaniem użytkownikami i procesem uwierzytelniania (który powinien działać jako usługa dedykowana) a kontrolą dostępu (która jest specyficzna dla każdej mikrousługi i powinna być obsługiwany lokalnie przez każdego z nich). Oczywiście, aby ułatwić obsługę, niektóre klienty administracyjne powinny dać kompleksowy przegląd kilku usług).

Christophe
źródło
1
Bardzo dobra rada tutaj. Podoba mi się pomysł z drugim tokenem.
Robert
1

Tutaj też jest krótka odpowiedź. Powinieneś sam wdrożyć wszystkie podstawowe funkcje, które chcesz zaoferować swoim „klientom”. Problematyczne wydaje się, aby klienci dodawali takie podstawowe zachowania, jak same uprawnienia użytkownika, ponieważ już wykonujesz uwierzytelnianie użytkownika; jeśli zostawisz to klientowi, aby go zaimplementować, może skończyć się „wspieraniem” wielu implementacji tego samego kodu uprawnień. Nawet jeśli nie jesteś „właścicielem”, w kodzie pojawią się błędy i chcesz, aby Twoi klienci mieli funkcjonalność, której oczekiwali, z uzasadnionego powodu, więc wspierasz rozwiązywanie problemów, które ma klient. Obsługa wielu baz kodu nie jest przyjemnością.

BenPen
źródło