2016-11-07 37 views
6

Kontekst: Tworzę platformę chmurową do obsługi wielu aplikacji przy użyciu SSO. Używam Keycloak do uwierzytelniania i Netflix Zuul do autoryzacji (bramka API) przez Keycloak Spring Security Adapter.Połączenia z Microservice do Microservice, autoryzacja z wiadomości kolejki

Każda mikroserwerka oczekuje nagłówka Authorization, który zawiera poprawny JWT, z którego będzie pobierać nazwę użytkownika (pod) w celu przetworzenia żądania. Każde połączenie z serwisu microservice do microservice powinno najpierw przejść przez Netflix Zuul, przekazując nagłówek Authorization, aby zachować weryfikację bezstanową. Ta strategia pozwala każdej mikroserwisowi wiedzieć, kto jest użytkownikiem (sub), który pośrednio wywołuje mikroserwis.

Problem/Pytanie 1: Co się stanie, gdy mikroserwis zostanie wywołany z komunikatu kolejki? Jedną z moich pomysłów było przechowywanie w kolejce informacji związanych z wiadomością + userInfo, a także utworzenie dedykowanej mikroserwisu do przetwarzania tego rodzaju wiadomości, przy takim podejściu ta specjalna mikroserwiska powinna odczytywać userInfo z kolejki i przetwarzać komunikat .

AKTUALIZACJA 1: Na wiadomość e-mail z odpowiedzi z innego forum, przechowywanie JWT w kolejce nie jest dobrym pomysłem, ponieważ może być łatwo wydobywane.

Problem/Pytanie 2: Ale co się stanie, jeśli poprzednie specjalny microservice chce wywołać inny normalny microservice które oczekują, aby otrzymać JWT w nagłówku? Czy ta specjalna mikroserwis powinien sam stworzyć JWT, aby podszyć się pod użytkownika i móc wywoływać zwykłe mikroserwisy?

Innym rozwiązaniem, które myślałem, było przechowywanie oryginalnego JWT w kolejce, ale co się stanie, jeśli kolejka wywoła później specjalne usługi mikroserwisowe? Zaraz po tym, jak JWT nie jest już ważny (wygasł), a usługa microservice odrzuci żądanie?

Możliwe rozwiązania: (Aktualizacja za João Angelo dyskusji, patrz niżej)

mam uwierzytelnić żądania od swoich użytkowników (autoryzacji przepływu kod) i mój usług (poświadczenia klienta przyznać) , oba żądania powinny zawierać informacje użytkownika w polu danych. Gdy żądanie pochodzi od użytkownika, muszę sprawdzić, czy informacje o użytkowniku ładunku są zgodne z oświadczeniami JWT. Kiedy żądanie pochodzi z usługi, po prostu muszę zaufać tej usłudze (o ile jest pod moją kontrolą).

Będę bardzo wdzięczny za pomoc. Dzięki.

Odpowiedz

5

Zrzeczenie się odpowiedzialności: Nigdy nie używałem Pliku, ale wiki tagów mówi, że jest zgodne z OAuth2, więc ufam tym informacjom.


Na widok naprawdę na wysokim poziomie, to wydaje się mieć dwa wymagania:

  1. uwierzytelniania działań wyzwalanych przez użytkownika końcowego, podczas gdy on używa systemu.
  2. uwierzytelnianie działań uruchamianych przez system w nieznanym czasie i gdy użytkownik końcowy nie musi być online.

Już spotkaliśmy się pierwszy, opierając się na systemie uwierzytelniania tokenów i chciałbym zrobić dokładnie to samo dla drugiego punktu, jedyną różnicą jest to, że żetony zostaną wydane do systemu za pomocą Przyznanie poświadczeń klienta OAuth2: zamiast innych dotacji kierowanych na scenariusze, w których znajduje się użytkownik końcowy.

Client Credentials Grant

(źródło: Client Credentials Grant)

W twoim przypadku, Keycloak będzie odgrywać rolę Auth0 i aplikacje klienckie są microservices który może utrzymać tajemnice klienckie służące do uwierzytelnienia się w serwerze autoryzacji i uzyskania dostęp do tokenów.

Jedno mieć na uwadze to, że jeśli system opiera się na twierdzeniu sub o wiele więcej niż uwierzytelniania i autoryzacji to być może trzeba dokonać pewnych korekt. Na przykład, widziałem systemy, w których wykonanie czynności A było wymagane, aby wiedzieć, że było ukierunkowane na użytkowników X i Y, ale ładunek dla działania otrzymał tylko użytkownik Y, a założony użytkownik X był bieżącą uwierzytelnioną jednostką główną. Działa to dobrze, gdy wszystko jest zsynchronizowane, ale jedynie przełączając ładunek, aby określić obu użytkowników, oznaczałoby to, że czynność mogła zostać wykonana asynchronicznie przez uwierzytelnionego użytkownika systemu.

+0

Witaj João, rozumiem, więc 1) mikroserwisy powinny oczekiwać zawsze JWT od użytkownika lub innej usługi. Właśnie wykonałem test i odkryłem, że niektóre różnice między JWT dla mikroserwisu w porównaniu z użytkownikiem nie zawierają roszczeń i zawierają dodatkowe pole "clientId", więc coś w stylu, jeśli JWT zawiera " clientId "nie jest użytkownikiem, ale usługą. Lub mogę polegać w polu "aud", jeśli "aud" odpowiada nazwie klienta w celu uwierzytelnienia użytkowników, to użytkownik, jeśli nie, to inna usługa. –

+0

2) Wydaje się, że muszę zawsze wysyłać identyfikator użytkownika w polu danych, aby usługa mogła przetworzyć żądania w przejrzysty sposób (usługa lub połączenie z użytkownikiem), jeśli stwierdzę, że połączenie pochodzi od użytkownika "aud" lub "clientId" Potrafię zweryfikować pole ładunku za pomocą "sub" lub "preferred_username", aby upewnić się, że wartość ładunku odpowiada użytkownikowi wykonującemu akcję. Ale w przypadku usługi, po prostu muszę zaufać użytkownikowi, który jest określony w ładowności? –

+0

Tak, to byłoby jedno podejście, sprawdź poprawność danych wejściowych, gdy pochodzą od użytkowników, aby upewnić się, że nie próbują podszywać się pod innych użytkowników i ufać im, gdy pochodzą one z Twoich własnych usług. Zakładając, że wszystkie mikrousługi są pod twoją kontrolą, wydaje się to odpowiednim podejściem. Wydaje się również prostsze niż przechowywanie tokenów dostępu i/lub odświeżanie tokenów, aby później można było wykonać połączenie, nawet jeśli użytkownik jest w trybie offline. –

0

Jedną z powszechnych konfiguracji jest posiadanie API gateway, która sprawdza wszystkie przychodzące żądania według ich JWT. Bramka API sprawdza poprawność podpisu JWT (lub odszyfrowuje go dla zaszyfrowanych JWT), sprawdza czas wygaśnięcia itp. I wyodrębnia z niego zakresy i identyfikator użytkownika (podrzędny).

Następnie porównuje zakresy z zestawem zdefiniowanych zakresów dla każdej usługi mikrto, a jeśli zakres zapewnia dostęp użytkownika (podmiotu), żądanie jest przekazywane do usługi mikro. Identyfikator użytkownika (sub w JWT) wraz z innymi potrzebnymi informacjami przechowywanymi w JWT jest umieszczany w nagłówkach zapytań niestandardowych, takich jak X-IGNACIO-SUBJECT