Staramy się ustalić najlepszy sposób autoryzacji użytkowników w architekturze mikrousług, jednocześnie zapewniając ograniczone uprawnienia mikrousług. Nasza architektura korzysta z centralnej usługi autoryzacji do obsługi wydawania tokenów JWT.
Mamy następujące wymagania:
Użytkownicy powinni mieć ograniczone możliwości wykonywania określonych ról. np. użytkownik powinien mieć możliwość tworzenia / modyfikowania / czytania treści, które posiada.
Mikrousługi powinny być ograniczone tylko do wymaganych uprawnień. np. mikrousługa, która musi tylko odczytywać dane z innej usługi, powinna być wyraźnie zabroniona zapisywania danych w tej usłudze.
Załóżmy na przykład, że mamy system, w którym użytkownicy mogą przesyłać zdjęcia do usługi magazynu obrazów. Mamy usługę tagowania, która automatycznie oznacza zdjęcia lokalizacją. Użytkownicy mogą CRUD tylko własne zdjęcia. Usługa tagowania może odczytać dowolny obraz z usługi magazynu obrazów, jednak nie powinna mieć możliwości modyfikacji / usuwania.
Jaki jest dobry sposób na osiągnięcie powyższego przy użyciu tokenów JWT? Niektóre omówione rozwiązania to:
Usługa magazynu obrazów udostępnia 2 interfejsy API, jeden dostępny zewnętrznie (dający użytkownikowi dostęp do CRUD), a drugi dostępny wewnętrznie (dający wewnętrzny dostęp tylko do odczytu). Wydaje się nieelastyczny - co jeśli inna usługa wewnętrzna potrzebuje dostępu do odczytu / zapisu do wszystkich obrazów (np. Taka, która automatycznie usuwa wyraźne obrazy)?
Ustawiliśmy dwa uprawnienia w JWT użytkownika, jeden to CRUD_OwnImages, drugi to READ_ForAnalysis. Usługa tagowania może sprawdzić, czy użytkownik ma uprawnienia READ_ForAnalysis, a jeśli tak, złóż odpowiednie żądanie. Mamy kolejną mikrousługę, która sprawdza, czy użytkownik ma CRUD_OwnImages do operacji CRUD na własnych obrazach użytkownika. To nakłada na każdą mikrousługę odpowiedzialność za zapewnienie, że użytkownik jest ograniczony do wymaganych działań. Dzięki temu podejściu magazyn obrazów nie ma możliwości ograniczenia każdej mikrousługi, dlatego jest potencjalnie płatkowy i podatny na błędy.
Dajemy mikroserwisowi tagowania własnego użytkownika, z uprawnieniem READ_ForAnalysis. Następnie, gdy usługa tagowania żąda obrazów z magazynu obrazów, ma do nich dostęp, ale nie wolno ich modyfikować. Użytkownik użytkownika ma tylko uprawnienie CRUD_OwnImages, więc może pobierać i uzyskiwać dostęp tylko do swoich obrazów z interfejsu użytkownika. Jeśli inna usługa potrzebuje CRUD do wszystkich danych, możemy nadać jej CRUD_AllData lub podobny. Podobało nam się to podejście, ponieważ każda usługa jest teraz odpowiedzialna za własne dane (zamiast tej logiki powielanej w wielu usługach), ale co, jeśli usługa wymaga zarówno uprawnień użytkownika, jak i uprawnień mikrousług? Czy możemy bezpiecznie wysyłać dwa tokeny JWT (zarówno użytkownika, jak i mikrousługę)? Czy istnieje sposób, aby bezpiecznie łączyć uprawnienia i przesyłać je przez? na przykład
Problem nasila się, jeśli informacje o użytkowniku są potrzebne w dalszej części procesu (w odległości 2 lub 3 mikrousług). Czy po prostu zakładamy, że od pojedynczych mikrousług zależą tylko działania, których potrzebują, a nie wyraźne?