Zabezpiecz swoje zasoby API dla komunikacji między maszynami
Dowiedz się, jak wykorzystać OAuth 2.0 i JWT do zabezpieczenia zasobów API dla komunikacji między maszynami.
Podczas tworzenia projektu, który obejmuje wiele usług, bezpieczeństwo zasobów API jest kluczową kwestią. W tym artykule pokażę, jak wykorzystać OAuth 2.0 i JWT do zabezpieczenia komunikacji między usługami (maszyna do maszyny) oraz jak zastosować kontrolę dostępu opartą na rolach (RBAC), aby przestrzegać zasady minimalnego przywileju.
Rozpocznij
Aby podążać za artykułem, zakładam, że masz następujące wymagania wstępne:
- Konto Logto Cloud lub samodzielnie hostowaną instancję Logto
- Przynajmniej dwie usługi, które muszą się komunikować między sobą
Dla celów demonstracyjnych załóżmy, że mamy następujące usługi:
- Usługa koszyka, która udostępnia API do zarządzania koszykami
- Punkt końcowy:
https://cart.example.com/api
- Punkt końcowy:
- Usługa płatności, która udostępnia API do przetwarzania płatności
- Punkt końcowy:
https://payment.example.com/api
- Punkt końcowy:
Przepływ uwierzytelniania
Teraz nasza usługa koszyka musi wywołać usługę płatności, aby przetworzyć płatności. Przepływ uwierzytelniania jest następujący:
Kilka kluczowych pojęć z powyższego diagramu:
- JWT (RFC 7519): JSON Web Token. Zobacz nasz poprzedni artykuł dla wprowadzenia do JWT.
- JWK (RFC 7517): JSON Web Key, który jest używany do weryfikacji podpisu JWT. Zestaw JWK to zestaw JWK.
- „client_credentials” grant (RFC 6749): Typ przyznania w OAuth 2.0. Używa poświadczeń klienta do uzyskania tokena dostępu. Szczegóły pokażemy w nadchodzących sekcjach.
Każdy uczestnik w powyższym diagramie ma do odegrania rolę w przepływie uwierzytelniania:
- Usługa koszyka: Klient, który musi wywołać usługę płatności. Chociaż jest to usługa, nadal jest klientem w kontekście OAuth 2.0, a takie klientów nazywamy „aplikacjami maszyna-do-maszyny” w Logto.
- Logto: Serwer autoryzacji OAuth 2.0, który wydaje tokeny dostępu.
- Usługa płatności: Zasób API, który udostępnia API do przetwarzania płatności.
Przeanalizujmy przepływ uwierzytelniania krok po kroku.
Wstępna konfiguracja
Aby przeprowadzić przepływ uwierzytelniania, musimy utworzyć aplikację maszyna-do-maszyny (usługę koszyka) oraz zasób API (usługę płatności) w Logto.
Tworzenie zasobu API
Ponieważ nasza usługa koszyka musi znać API usługi płatności podczas uwierzytelniania, musimy najpierw utworzyć zasób API. Przejdź do Konsoli Logto, kliknij Zasoby API w lewym pasku bocznym i kliknij Utwórz zasób API. W otwartym oknie dialogowym oferujemy kilka samouczków, aby pomóc Ci zacząć. Możesz także kliknąć Kontynuuj bez samouczka, aby go pominąć.
Wpisz nazwę API i identyfikator, na przykład „Usługa płatności” i „https://payment.example.com/api”, a następnie kliknij Utwórz zasób API.
Po utworzeniu zasobu API zostaniesz przekierowany na stronę szczegółów. Na razie możemy zostawić to tak, jak jest.
Tworzenie aplikacji maszyna-do-maszyny
Kliknij Aplikacje w lewym pasku bocznym i kliknij Utwórz aplikację. W otwartym oknie dialogowym znajdź kartę Maszyna-do-maszyny, a następnie kliknij Rozpocznij budowę.
Podaj nazwę aplikacji, na przykład „Usługa koszyka”, a następnie kliknij Utwórz aplikację. Zostanie wyświetlony interaktywny przewodnik, który pomoże Ci skonfigurować aplikację. Możesz śledzić przewodnik, aby zrozumieć podstawowe użycie, lub kliknąć Zakończ i gotowe, aby go pominąć.
Żądanie tokena dostępu
Ponieważ aplikacje maszyna-do-maszyny zakłada się, że są bezpieczne (np. są wdrożone w sieci prywatnej), możemy użyć grantu „client_credentials” OAuth 2.0, aby uzyskać token dostępu. Używa podstawowego uwierzytelnienia do uwierzytelnienia klienta:
- URL żądania to punkt końcowy tokena Twojej instancji Logto. Możesz go znaleźć i skopiować w karcie Zaawansowane ustawienia na stronie szczegółów aplikacji maszyna-do-maszyny.
- Metoda żądania to
POST
. - Nagłówek
Content-Type
żądania toapplication/x-www-form-urlencoded
. - Dla nagłówka
Authorization
wartość toBasic <base64(app_id:app_secret)>
, gdzieapp_id
iapp_secret
to odpowiednio ID aplikacji i sekret aplikacji maszyna-do-maszyny. Możesz je znaleźć na stronie szczegółów aplikacji. - Treść żądania musi określać typ grantu i identyfikator API. Na przykład,
grant_type=client_credentials&resource=https://payment.example.com/api
.grant_type=client_credentials
: Stała wartość dla grantu „client_credentials”.resource=https://payment.example.com/api
: Identyfikator API zasobu API, do którego klient chce uzyskać dostęp.- Jeśli aplikacja musi być autoryzowana za pomocą zakresów (uprawnień), możesz również określić zakresy w treści żądania. Na przykład,
scope=read:payment write:payment
. Omówimy zakresy później.
Oto przykład żądania przy użyciu curl
:
Pomyślny korpus odpowiedzi wyglądałby tak:
Wyślij żądanie z nagłówkiem autoryzacji
Teraz mamy token dostępu i możemy go dołączyć do nagłówka Authorization
żądania do zasobu API. Na przykład, jeśli chcemy wywołać API POST /payments
usługi płatności, możemy wysłać następujące żądanie:
Zwaliduj JWT
Możesz zauważyć, że usługa płatności musi zwalidować JWT przy użyciu zestawu JWK, i może mieć lokalną pamięć podręczną zestawu JWK, aby uniknąć pobierania zestawu JWK z Logto za każdym razem. Na szczęście, dzięki popularności JWT, istnieje wiele bibliotek, które mogą pomóc osiągnąć ten cel kilkoma liniami kodu.
Te biblioteki są zwykle nazywane „jose” (JavaScript Object Signing and Encryption) lub „jsonwebtoken”. Na przykład, w Node.js możemy użyć jose do zwalidowania JWT:
Jeśli walidacja powiedzie się, zmienna payload
będzie zdekodowanym ładunkiem JWT. W przeciwnym razie zostanie wyrzucony błąd.
Zastosuj kontrolę dostępu opartą na rolach
Teraz skutecznie zabezpieczyliśmy komunikację między usługą koszyka a usługą płatności. Jednak przepływ uwierzytelniania tylko zapewnia, że klient to prawdziwa usługa koszyka, ale nie gwarantuje, że usługa koszyka ma jakiekolwiek uprawnienia do wykonywania działań na usłudze płatności.
Załóżmy, że chcemy pozwolić usłudze koszyka na tworzenie płatności, ale nie na odczytywanie płatności.
Definiowanie uprawnień
W Logto „zakresy” i „uprawnienia” są zamienne. Przejdź do strony szczegółów zasobu API usługi płatności i przejdź na kartę Uprawnienia. Powinna być teraz pusta. Kliknij Utwórz uprawnienie, wpisz read:payment
jako nazwę uprawnienia i wpisz Odczytaj płatności
jako opis uprawnienia. Następnie kliknij Utwórz uprawnienie.
Powtórz powyższe kroki, aby utworzyć kolejne uprawnienie o nazwie write:payment
i opisie Utwórz płatności
.
Utwórz rolę maszyna-do-maszyny
Rola to grupa uprawnień. W Logto, aplikacje maszyna-do-maszyny mogą być przypisane role w celu przyznania uprawnień. Kliknij „Role” w lewym pasku bocznym i kliknij Utwórz rolę.
- Wpisz
checkout
jako nazwę roli i wpiszUsługa kasa
jako opis roli. - Kliknij Pokaż więcej opcji. Wybierz „Rola aplikacji maszyna-do-maszyny” jako typ roli.
- W sekcji „Przypisane uprawnienia” kliknij ikonę strzałki po lewej stronie nazwy zasobu API (Usługa płatności) i wybierz uprawnienie
write:payment
. - Kliknij Utwórz rolę.
- Ponieważ już mamy aplikację maszyna-do-maszyny (Usługa koszyka), możemy bezpośrednio przypisać rolę do niej w następnym kroku. Zaznacz pole wyboru po lewej stronie nazwy aplikacji (Usługa koszyka) i kliknij Przypisz aplikacje.
Żądanie tokena dostępu z zakresami
Oprócz parametrów treści żądania, które wspomnieliśmy w Żądanie tokena dostępu, możemy również określić zakresy w treści żądania. Na przykład, jeśli chcemy zażądać uprawnień write:payment
, możemy wysłać następujące żądanie:
Aby zażądać wielu zakresów, możesz oddzielić je spacjami. Na przykład, scope=write:payment read:payment
.
Walidacja zakresów
Jeśli działanie wymaga uprawnień write:payment
w usłudze płatności, możemy zwalidować zakresy poprzez zapewnienie, że roszczenie scope
ładunku JWT zawiera oczekiwany zakres:
Podsumowanie
Jeśli chcesz chronić dostęp do usługi koszyka, możesz również zastosować ten sam przepływ uwierzytelniania. Tym razem usługa koszyka jest zasobem API, a klientem jest inna usługa, która musi uzyskać dostęp.
Dzięki Logto, Twoje zasoby API są zabezpieczone za pomocą OAuth 2.0 i JWT, a Ty możesz przestrzegać zasady minimalnego przywileju, stosując kontrolę dostępu opartą na rolach. Ponadto możesz również używać Logto, aby zarządzać swoimi użytkownikami i ich uprawnieniami, a nawet zintegrować się z zewnętrznymi dostawcami tożsamości.