Säkra dina API-resurser för maskin-till-maskin kommunikation
Lär dig hur du utnyttjar OAuth 2.0 och JWT för att säkra dina API-resurser för maskin-till-maskin kommunikation.
När du bygger ett projekt som involverar flera tjänster är säkerheten för API-resurserna en kritisk fråga. I den här artikeln visar jag hur du använder OAuth 2.0 och JWT för att säkra kommunikationen mellan tjänster (maskin-till-maskin), och hur du tillämpar rollbaserad åtkomstkontroll (RBAC) för att följa minsta privilegsprincipen.
Kom igång
För att följa med, förutsätter jag att du har följande förutsättningar:
- Ett Logto Cloud-konto, eller en självhostad Logto-instans
- Minst två tjänster som behöver kommunicera med varandra
För demonstrationsändamål, låt oss anta att vi har följande tjänster:
- En varukorgstjänst som tillhandahåller API:er för att hantera varukorgar
- Slutpunkt:
https://cart.example.com/api
- Slutpunkt:
- En betaltjänst som tillhandahåller API:er för att behandla betalningar
- Slutpunkt:
https://payment.example.com/api
- Slutpunkt:
Autentiseringsflöde
Nu behöver vår varukorgstjänst anropa betaltjänsten för att behandla betalningar. Autentiseringsflödet är som följer:
Några viktiga koncept i diagrammet ovan:
- JWT (RFC 7519): JSON Web Token. Se vår tidigare artikel för en introduktion till JWT.
- JWK (RFC 7517): JSON Web Key som används för att verifiera signaturen av en JWT. Ett JWK-set är en uppsättning av JWK:ar.
- "client_credentials" grant (RFC 6749): En grant-typ i OAuth 2.0. Den använder klientens uppgifter för att erhålla en åtkomsttoken. Vi kommer att demonstrera detaljerna i de kommande sektionerna.
Varje deltagare i diagrammet ovan har en roll att spela i autentiseringsflödet:
- Varukorgstjänst: Klienten som behöver anropa betaltjänsten. Även om det är en tjänst, är det fortfarande en klient i OAuth 2.0-kontexten, och vi kallar sådana klienter för "maskin-till-maskin-applikationer" i Logto.
- Logto: OAuth 2.0-auktoriseringsservern som utfärdar åtkomsttoken.
- Betaltjänst: API-resursen som tillhandahåller API:er för att behandla betalningar.
Låt oss gå igenom autentiseringsflödet steg för steg.
Initial inställning
För att genomföra autentiseringsflödet måste vi skapa en maskin-till-maskin-app (varukorgstjänst) och en API-resurs (betaltjänst) i Logto.
Skapa API-resurs
Eftersom vår varukorgstjänst behöver vara medveten om betaltjänstens API vid autentisering, måste vi skapa en API-resurs först. Gå till Logto Console, klicka på API-resurser i vänstra sidomenyn och klicka på Skapa API-resurs. I den öppnade dialogrutan erbjuder vi några handledningar för att hjälpa dig komma igång. Du kan också klicka på Fortsätt utan handledning för att hoppa över den.
Ange API-namnet och identifikatorn, till exempel Betaltjänst
och https://payment.example.com/api
, klicka sedan på Skapa API-resurs.
Efter att ha skapat API-resursen kommer du att omdirigeras till detaljsidan. Vi kan lämna den som den är för tillfället.
Skapa maskin-till-maskin-app
Klicka på Applikationer i vänstra sidomenyn och klicka på Skapa applikation. I den öppnade dialogen, hitta Maskin-till-maskin-kortet, klicka sedan på Börja bygga.
Ange applikationsnamnet, till exempel Varukorgstjänst
, och klicka på Skapa applikation. En interaktiv guide visas för att hjälpa dig ställa in applikationen. Du kan följa guiden för att förstå den grundläggande användningen, eller klicka på Klart och klar för att hoppa över den.
Begär åtkomsttoken
Eftersom maskin-till-maskin-applikationer antas vara säkra (t.ex. de är distribuerade i ett privat nätverk), kan vi använda OAuth 2.0 "client_credentials" grant för att erhålla en åtkomsttoken. Den använder grundläggande autentisering för att autentisera klienten:
- Begärans URL är token-slutpunkten för din Logto-instans. Du kan hitta och kopiera den på fliken Avancerade inställningar på maskin-till-maskin-appens detaljsida.
- Begärans metod är
POST
. - Begärans
Content-Type
-huvud ärapplication/x-www-form-urlencoded
. - För
Authorization
-huvudet är värdetBasic <base64(app_id:app_secret)>
, därapp_id
ochapp_secret
är appens ID och appens hemlighet för maskin-till-maskin-appen respektive. Du kan hitta dem på applikationens detaljsida. - Begärans kropp behöver specificera grant-typen och API-identifikatorn. Till exempel,
grant_type=client_credentials&resource=https://payment.example.com/api
.grant_type=client_credentials
: Det konstanta värdet för "client_credentials" grant.resource=https://payment.example.com/api
: API-identifikatorn för API-resursen som klienten vill komma åt.- Om applikationen behöver auktoriseras med scopes (behörigheter), kan du också specificera scopes i begärans kropp. Till exempel,
scope=read:payment write:payment
. Vi kommer att täcka scopes senare.
Här är ett exempel på begäran med curl
:
En framgångsrik svarskropp skulle se ut så här:
Skicka begäran med auktorisationshuvud
Nu har vi åtkomsttoken, och vi kan lägga den till Authorization
-huvudet i begäran till API-resursen. Till exempel, om vi vill anropa POST /payments
API:t för betaltjänsten, kan vi skicka följande begäran:
Validera JWT
Du kan märka att betaltjänsten behöver validera JWT med hjälp av JWK-set, och kan ha en lokal JWK-set cache för att undvika att hämta JWK-set från Logto varje gång. Lyckligtvis, på grund av JWT:s popularitet, finns det många bibliotek som kan hjälpa dig att uppnå målet med några rader kod.
Dessa bibliotek kallas vanligtvis "jose" (JavaScript Object Signing and Encryption) eller "jsonwebtoken". Till exempel, i Node.js kan vi använda jose för att validera JWT:
Om valideringen lyckas, kommer payload
-variabeln att vara dekodad JWT-payload. Annars kommer ett fel att kastas.
Tillämpa rollbaserad åtkomstkontroll
Nu har vi framgångsrikt säkrat kommunikationen mellan varukorgstjänsten och betaltjänsten. Men autentiseringsflödet säkerställer endast att klienten är den verkliga varukorgstjänsten, men säkerställer inte att varukorgstjänsten har någon behörighet att utföra åtgärder på betaltjänsten.
Låt oss säga att vi vill tillåta varukorgstjänsten att skapa betalningar, men inte att läsa betalningar.
Definiera behörigheter
I Logto är "scopes" och "behörigheter" utbytbara. Gå till API-resursens detaljsida för betaltjänsten och navigera till fliken Behörigheter. Den borde vara tom nu. Klicka på Skapa behörighet, ange read:payment
som behörighetsnamn, och ange Läsa betalningar
som behörighetsbeskrivning. Klicka sedan på Skapa behörighet.
Upprepa ovanstående steg för att skapa en annan behörighet med namnet write:payment
och beskrivningen Skapa betalningar
.
Skapa maskin-till-maskin roll
En roll är en grupp av behörigheter. I Logto kan maskin-till-maskin-appar tilldelas roller för att bevilja behörigheter. Klicka på "Roller" i vänstra sidomenyn och klicka på Skapa roll.
- Ange
checkout
som rollnamn och angeKassaservice
som rollbeskrivning. - Klicka på Visa fler alternativ. Välj "Maskin-till-maskin-appar roll" som rolltyp.
- I "Tilldelade behörigheter"-sektionen, klicka på pilikonen till vänster om API-resursens namn (Betaltjänst), och välj
write:payment
behörigheten. - Klicka på Skapa roll.
- Eftersom vi redan har en maskin-till-maskin-app (Varukorgstjänst), kan vi direkt tilldela rollen till den i nästa steg. Markera kryssrutan till vänster om appens namn (Varukorgstjänst), och klicka på Tilldela applikationer.
Begär åtkomsttoken med scopes
Förutom de begäranskroppsparametrar vi nämnde i Begär åtkomsttoken, kan vi också specificera scopes i begäranskroppen. Till exempel, om vi vill begära write:payment
behörigheten, kan vi skicka följande begäran:
För att begära flera scopes, kan du separera dem med mellanslag. Till exempel, scope=write:payment read:payment
.
Validera scopes
Om en åtgärd behöver write:payment
-behörigheten i betaltjänsten, kan vi validera scopes genom att försäkra oss om att scope
-anspråket i JWT-payload är:
Slutsats
Om du vill skydda åtkomsten till varukorgstjänsten kan du också tillämpa samma autentiseringsflöde. Den här gången är varukorgstjänsten API-resursen, och klienten är en annan tjänst som behöver åtkomma.
Med Logto är dina API-resurser säkrade med OAuth 2.0 och JWT, och du kan följa minsta privilegsprincipen genom att tillämpa rollbaserad åtkomstkontroll. Dessutom kan du också använda Logto för att hantera dina användare och deras behörigheter, och till och med integrera med tredjepartsidentitetsleverantörer.