Nederlands
  • oauth
  • jwt
  • api
  • security
  • authentication
  • authorization
  • machine-to-machine

Beveilig je API-bronnen voor machine-to-machine communicatie

Leer hoe je OAuth 2.0 en JWT kunt gebruiken om je API-bronnen te beveiligen voor machine-to-machine communicatie.

Gao
Gao
Founder

Bij het bouwen van een project met meerdere diensten is de beveiliging van de API-bronnen een kritisch punt. In dit artikel laat ik je zien hoe je OAuth 2.0 en JWT kunt gebruiken om de communicatie tussen diensten (machine-to-machine) te beveiligen, en hoe je rolgebaseerde toegangscontrole (RBAC) kunt toepassen om het minimum privilege-principe te volgen.

Aan de slag

Om mee te doen, neem ik aan dat je de volgende vereisten hebt:

  • Een Logto Cloud-account, of een zelf-gehoste Logto-instantie
  • Ten minste twee diensten die met elkaar moeten communiceren

Voor demonstratiedoeleinden nemen we aan dat we de volgende diensten hebben:

  • Een winkelwagenservice die API's biedt om winkelwagens te beheren
    • Endpoint: https://cart.example.com/api
  • Een betalingsservice die API's biedt om betalingen te verwerken
    • Endpoint: https://payment.example.com/api

Authenticatieflow

Nu moet onze winkelwagenservice de betalingsservice aanroepen om betalingen te verwerken. De authenticatieflow is als volgt:

Enkele sleutelaspecten in het bovenstaande diagram:

  • JWT (RFC 7519): JSON Web Token. Zie ons vorige artikel voor een introductie tot JWT.
  • JWK (RFC 7517): JSON Web Key die wordt gebruikt om de handtekening van een JWT te verifiëren. Een JWK-set is een verzameling JWK's.
  • "client_credentials" grant (RFC 6749): Een grant type in OAuth 2.0. Het gebruikt de inloggegevens van de client om een toegangstoken te verkrijgen. We zullen de details demonstreren in de komende secties.

Elke deelnemer in het bovenstaande diagram heeft een rol in de authenticatieflow:

  • Winkelwagenservice: De client die de betalingsservice moet aanroepen. Hoewel het een dienst is, is het nog steeds een client in de OAuth 2.0-context, en we noemen zulke clients "machine-to-machine applicaties" in Logto.
  • Logto: De OAuth 2.0-autorisatieserver die toegangstokens uitgeeft.
  • Betalingsservice: De API-bron die API's biedt om betalingen te verwerken.

Laten we de authenticatieflow stap voor stap doorlopen.

Initiële setup

Om de authenticatieflow uit te voeren, moeten we een machine-to-machine app (winkelwagenservice) en een API-bron (betalingsservice) maken in Logto.

Creëer API-bron

Aangezien onze winkelwagenservice op de hoogte moet zijn van de API van de betalingsservice tijdens de authenticatie, moeten we eerst een API-bron maken. Ga naar Logto Console, klik op API-bronnen in de linkerzijbalk en klik op Maak API-bron. In de geopende dialoog bieden we enkele tutorials aan om je op weg te helpen. Je kunt ook op Doorgaan zonder tutorial klikken om deze over te slaan.

Voer de API-naam en -identifier in, bijvoorbeeld Betalingsservice en https://payment.example.com/api, en klik dan op Maak API-bron.

Na het maken van de API-bron wordt je doorgestuurd naar de detailpagina. We kunnen het voorlopig laten zoals het is.

Maak machine-to-machine app

Klik op Toepassingen in de linkerzijbalk, en klik op Maak toepassing. In de geopende dialoog, vind de Machine-to-machine kaart en klik dan op Begin bouwen.

Voer de toepassingsnaam in, bijvoorbeeld Winkelwagenservice, en klik op Maak toepassing. Er wordt een interactieve gids getoond om je te helpen de toepassing in te stellen. Je kunt de gids volgen om de basisgebruik te begrijpen, of klik op Voltooi en klaar om deze over te slaan.

Vraag toegangstoken aan

Aangezien machine-to-machine applicaties als veilig worden beschouwd (bijv. ze zijn geïmplementeerd in een privaat netwerk), kunnen we de OAuth 2.0 "client_credentials" grant gebruiken om een toegangstoken te verkrijgen. Het gebruikt basis authenticatie om de client te authenticeren:

  • De aanvraag-URL is het token-eindpunt van je Logto-instantie. Je kunt het vinden en kopiëren in het Geavanceerde instellingen tabblad van de details pagina van de machine-to-machine app.
  • De aanvraagmethode is POST.
  • De aanvraag Content-Type header is application/x-www-form-urlencoded.
  • Voor de Authorisatie header is de waarde Basic <base64(app_id:app_secret)>, waar app_id en app_secret de app ID en app secret van de machine-to-machine app zijn. Je kunt ze vinden op de toepassingsdetailpagina.
  • De aanvraag-body moet het grant type en de API-identifier specificeren. Bijvoorbeeld, grant_type=client_credentials&resource=https://payment.example.com/api.
    • grant_type=client_credentials: De constante waarde voor de "client_credentials" grant.
    • resource=https://payment.example.com/api: De API-identifier van de API-bron die de client wil bereiken.
    • Als de applicatie geautoriseerd moet worden met scopes (toestemmingen), kun je ook de scopes specificeren in de aanvraag-body. Bijvoorbeeld, scope=read:payment write:payment. We zullen scopes later behandelen.

Hier is een voorbeeld van de aanvraag met curl:

Een succesvol reactiebody zou er als volgt uitzien:

Stuur aanvraag met autorisatieheader

Nu hebben we het toegangstoken, en we kunnen het toevoegen aan de Authorisatie header van de aanvraag naar de API-bron. Bijvoorbeeld, als we de POST /payments API van de betalingsservice willen aanroepen, kunnen we de volgende aanvraag sturen:

Valideer JWT

Je merkt misschien op dat de betalingsservice de JWT moet valideren met behulp van de JWK-set, en mogelijk een lokale JWK-set-cache heeft om te voorkomen dat de JWK-set elke keer van Logto wordt opgehaald. Gelukkig zijn er, dankzij de populariteit van JWT, veel bibliotheken die je kunnen helpen om het doel te bereiken met een aantal regels code.

Deze bibliotheken worden meestal "jose" (JavaScript Object Signing and Encryption) of "jsonwebtoken" genoemd. We kunnen bijvoorbeeld in Node.js jose gebruiken om de JWT te valideren:

Als de validatie slaagt, zal de payload-variabele de gedecodeerde JWT-payload zijn. Anders wordt er een fout afgeworpen.

Pas rolgebaseerde toegangscontrole toe

Nu we de communicatie tussen de winkelwagenservice en de betalingsservice met succes hebben beveiligd. De authenticatieflow zorgt er echter alleen voor dat de client de echte winkelwagenservice is, maar niet ervoor dat de winkelwagenservice toestemming heeft om acties uit te voeren op de betalingsservice.

Stel dat we de winkelwagenservice toestaan om betalingen te creëren, maar niet om betalingen te lezen.

Definieer permissies

In Logto zijn "scopes" en "permissies" uitwisselbaar. Ga naar de API-bronderegisterpagina van de betalingsservice, en navigeer naar het tabblad Permissies. Het zou nu leeg moeten zijn. Klik op Maak permissie, voer read:payment in als de permissienaam en Lees betalingen in als de permissieomschrijving. Klik dan op Maak permissie.

Herhaal de bovenstaande stappen om een andere permissie te maken met de naam write:payment en de omschrijving Maak betalingen.

Maak machine-to-machine rol

Een rol is een groep permissies. In Logto kunnen machine-to-machine apps rollen toegewezen krijgen om permissies te verlenen. Klik op "Rollen" in de linkerzijbalk en klik op Maak rol.

  1. Voer afrekenen in als de rolnaam en Afrekenservice als de rolomschrijving.
  2. Klik op Toon meer opties. Kies "Machine-to-machine app rol" als roltijd.
  3. In de sectie "Toegewezen permissies", klik op het pijltje links van de API-bronnaam (Betalingsservice), en selecteer de write:payment permissie.
    Maak rol
  4. Klik op Maak rol.
  5. Aangezien we al een machine-to-machine app hebben (Winkelwagenservice), kunnen we de rol direct toewijzen aan de volgende stap. Vink het selectievakje links van de toepassingsnaam (Winkelwagenservice) aan en klik op Toepassingen toewijzen.
Rol toewijzen aan toepassing

Vraag toegangstoken aan met scopes

Naast de aanvraag-bodyparameters die we hebben genoemd in Vraag toegangstoken aan, kunnen we ook de scopes specificeren in de aanvraag-body. Bijvoorbeeld, als we de write:payment permissie willen aanvragen, kunnen we de volgende aanvraag sturen:

Om meerdere scopes aan te vragen, kun je ze scheiden met spaties. Bijvoorbeeld, scope=write:payment read:payment.

Valideer scopes

Als een actie de write:payment permissie in de betalingsservice nodig heeft, kunnen we de scopes valideren door te controleren of de scope claim van de JWT-payload:

Conclusie

Als je de toegang tot de winkelwagenservice wilt beschermen, kun je ook dezelfde authenticatieflow toepassen. Deze keer is de winkelwagenservice de API-bron en is de client een andere dienst die toegang nodig heeft.

Met Logto zijn je API-bronnen beveiligd met OAuth 2.0 en JWT, en kun je het minimum privilege-principe volgen door rolgebaseerde toegangscontrole toe te passen. Bovendien kun je Logto ook gebruiken om je gebruikers en hun toestemming te beheren, en zelfs te integreren met externe identiteitsproviders.