Gérer vos API avec Gravitee.io !

Magazine
Marque
GNU/Linux Magazine
Numéro
251
Mois de parution
septembre 2021
Spécialité(s)


Résumé

Que ce soit pour des raisons business ou réglementaires, exposer des API à des tiers est aujourd’hui une nécessité pour de nombreuses entreprises. Mais comment sécuriser simplement les accès à des API utilisant parfois des technologies ou protocoles hétérogènes ? Comment garantir une qualité de service adaptée aux besoins des utilisateurs ? Ces deux questions ne sont pas les seules à se poser et lorsque le nombre d’API est important, cela peut devenir compliqué à gérer. Pour nous aider dans cette tâche, il existe des solutions d'API Management.


Body

Les API (Application Programming Interface) font partie du quotidien des développeurs, que ce soit pour des librairies ou pour des services distants, nous utilisons ses contrats d’interface afin d’interagir avec eux. Ces interfaces jouent le rôle de couche d’isolation entre notre application et le service (ou la librairie) utilisé, en permettant aux développeurs du service de faire évoluer le code sans nous impacter, tant que le contrat d’interface est respecté. Ces dernières années, le terme API est utilisé de manière générique pour parler des services distants exposant une API, le plus souvent de type REST. Avec l’avènement des architectures microservices et la nécessité de faire appel à des offres SaaS pour réduire les coûts ou les temps de réalisation, rares sont les projets où les API ne jouent pas un rôle prépondérant. Pour nous aider dans leur gestion, les solutions d’API Management ont fait leur apparition autour des années 2010 et ne cessent de gagner en popularité. Du point de vue du producteur d’API, elles ont pour but de faciliter la distribution, le contrôle et l’analyse de l’usage des API. Du point de vue du consommateur, elles vont en faciliter l’usage en proposant un moyen simple d’obtenir de la documentation et de souscrire aux API. Il existe différentes solutions d’API Management open source comme WSO2 [1], pour n’en citer qu’une. Dans cet article, je vous propose de partir à la découverte de Gravitee.io [2], une plate-forme d’API qui se veut simple d’utilisation et performante.

Dans la première partie, je vous présenterai de manière succincte les différents services qui composent cette plate-forme, puis dans un second temps, nous passerons à la pratique en présentant comment exposer et sécuriser une API.

L’environnement de test basé sur docker-compose est disponible sur GitHub [3].

1. Gravitee.io

La plate-forme Gravitee.io se compose de deux produits dans sa version open source sous licence Apache v2, APIM, pour « API Management », qui offre, comme son nom l’indique, toutes les fonctionnalités nécessaires à la gestion d’API et AM, pour « Access Management », qui permet la gestion d’identité et l’authentification. Ces deux produits sont complémentaires, mais peuvent très bien fonctionner de manière indépendante.

1.1 APIM

APIM permet la mise en place de la gouvernance d’API à proprement parler à travers différents services, la « Management API » et la « Gateway ». Ces deux services offrent un système de plugins qui leur permet d’être extensibles.

Définitions

  • API : il s’agit de la notion principale manipulée au sein d’APIM, elle représente la déclaration d’un service que vous souhaitez exposer au travers des Gateways.
  • Plan : les plans sont des contrats d’utilisation de vos API, ils permettent de spécifier les limites d’usage accordées aux utilisateurs y souscrivant. Une API peut avoir plusieurs plans qui vont spécifier le nombre de requêtes maximales sur un intervalle de temps, les mécanismes de sécurisation et d’authentification, etc.
  • Application : c’est l’élément sur lequel un consommateur d’API va attacher ses souscriptions. Une application représente assez naturellement le site, l’application mobile ou le service créés par le développeur utilisant l’API.
  • Souscription : il s’agit de l’abonnement d’un utilisateur à un plan d’usage pour une API et une application données. Une souscription a une durée de vie limitée et peut être révoquée à tout moment par l’éditeur de l’API.

1.1.1 Management API

La « Management API » permet la déclaration et le pilotage de vos API à l’aide d’une API REST. Deux applications web sont disponibles pour interagir avec ce service, la console de gestion et le portail développeurs. La console est à destination des éditeurs d’API en leur servant de console d’administration. Au travers de cette interface, un utilisateur disposant des droits appropriés va pouvoir déclarer des API, leur associer des plans d’usage et les déployer sur les instances de Gateway. Une fois les API déployées, il sera en mesure de consulter la liste des utilisateurs d’API, consulter des journaux d’événements et autres métriques.

Le portail développeurs quant à lui est à destination des consommateurs d’API. Il permet de rechercher des API, d’y souscrire selon un plan d’usage et d’obtenir de la documentation. Mais aussi de gérer des applications.

1.1.2 Gateway

La « Gateway » est l’élément critique de APIM. En effet, c’est à travers elle que le flux à destination de vos API transitera et elle aura en charge non seulement de router les requêtes vers la bonne API, mais aussi, et surtout, de valider que la requête est légitime et que l’émetteur respecte bien les règles définies via la console, comme le nombre de requêtes maximales sur un intervalle de temps donné ou tout simplement, le droit d’exécuter une requête de modification sur une ressource.

1.1.3 Cycle de vie d’une API et d’un plan

Une API peut avoir différents états. Ils ont pour but de faciliter la gestion des API au cours du temps en permettant ou non certaines actions (voir figure 1).

img 001 gravitee-api-lifecycle

Fig. 1 : Cycle de vie d’une API.

Le premier état est celui qui vient immédiatement après la création de l’API. Lorsqu’une API est en état « CREATED », elle n’est visible que de la console. Lorsque l’éditeur de l’API est satisfait de la configuration, il peut la passer en « PUBLISHED ». Dans cet état, l’API devient visible dans le portail développeurs et des souscriptions peuvent être créées. Si l’on souhaite temporairement limiter les souscriptions à une API, il est possible de la passer dans l’état « UNPUBLISHED ». Lorsque l’API arrive en fin de vie et que l’on ne souhaite plus apporter de modifications ni autoriser de souscriptions, nous pouvons la passer dans l’état « DEPRECATED ». Enfin, une fois que les services exposés par l’API ne sont plus utilisés et que chaque utilisateur a été notifié de leur fin de vie, il est possible de les décommissionner et de passer l’API à l’état « ARCHIVED ».

Les plans ont également un cycle de vie. La phase de création et de mise au point se nomme « STAGING », dans cet état les plans ne sont pas utilisables, car non publiés dans le portail. Vient ensuite la phase « PUBLISHED » qui permet à un développeur de voir le plan associé à l’API sur le portail et d’y souscrire. Lorsque l’on souhaite interdire de nouvelles souscriptions, il faut passer le plan dans la phase « DEPRECATED » avant de pouvoir le clore (voir figure 2).

img 002 gravitee-plan-lifecycle

Fig. 2 : Cycle de vie d’un plan.

Ces cycles de vie sont liés à la publication d’informations dans le portail développeurs. Au niveau de la Gateway, une API a un cycle de vie plus simple : elle est soit absente de la Gateway soit déployée. Une fois déployée, elle peut être démarrée ou stoppée sans autre état. Les plans, eux, ne sont pas soumis à un état particulier dans la Gateway, car ils sont partie intégrante de la définition de l’API.

1.2 AM

Lorsque l’on parle d’API Management, l’identification et le contrôle de droits sont des aspects importants. C’est à cette problématique que le produit AM répond. Dans sa version open source, il implémente entre autres les protocoles standard OAuth2 [4] et OpenID Connect [5] et se veut simple d’utilisation. Tout comme APIM, ce produit est composé de deux services et dispose d’un système de plugins qui lui permet d’être extensible.

Définitions

  • Domaine de sécurité : un domaine est l’élément principal dans AM. Il va permettre de définir les options d’authentification des utilisateurs, les applications ainsi que les différents fournisseurs d’identité.
  • Application : l’application est attachée à un domaine. Elle identifie une application autorisée à identifier un utilisateur à l’aide de AM. Il s’agit d’un « Client » au sens OAuth2.
  • Fournisseur d’identité : Les fournisseurs d’identité (ou Identity Provider) sont des plugins AM ou des services tiers qui gèrent l’identité des utilisateurs, ils permettent ainsi leur authentification et fournissent certaines informations de profil (comme le nom, le prénom, l’e-mail), en fonction des autorisations demandées.

1.2.1 Management Service

Le « Management Service » permet la déclaration et le pilotage de vos domaines de sécurité à l’aide d’une API REST et d’une application web. Au travers de cette interface, il vous sera possible de définir les applications, les modalités d’identification comme le multifacteur ou du WebAuthn [6]. Au-delà des aspects configuration, ce service propose également des journaux d’audits afin de tracer les différentes actions d’administration sur le domaine, ainsi que des tableaux de bord permettant de visualiser rapidement le nombre d’utilisateurs par application, les applications les plus utilisées, le nombre d’authentifications en échec, etc.

1.2.2 Gateway

La « Gateway » est un service qui va jouer le rôle du serveur d’autorisation au sens OAuth2. C’est ce service qui va être chargé de dérouler les différentes étapes d’authentification et d’autorisation afin de délivrer un token permettant à l’utilisateur d’accéder à la ressource demandée.

Après cette rapide présentation des différents produits, passons à un peu de pratique.

2. Prise en main

Dans cette section, nous allons découvrir la plate-forme Gravitee.io à l’aide d’un exemple simple, mais je l’espère suffisamment complet pour ne pas vous laisser sur votre faim. Dans cet exemple, nous allons donner accès à un service nommé Petstore dont la spécification [7] est disponible en ligne au format OpenAPI [8]. À l’heure où cet article est écrit, la dernière version disponible de Gravitee est la 3.6.0.

2.1 Démarrage de la plate-forme

Avant toute chose, lançons les différents services. Pour cela, nous allons utiliser un docker-compose dérivé de celui fourni par le GitHub de Gravitee.io. Il a été modifié pour y ajouter l’image du service Petstore et apporter quelques modifications de configuration.

$ git clone https://github.com/leleueri/demo-gravitee.git gravitee-linux-magazine

Le fichier docker-compose.yml contient la définition des différents services Gravitee.io, de MongoDB et d’Elasticsearch utilisés comme stockage de données du service Petstore que nous souhaitons exposer à nos utilisateurs et enfin de Traefik, qui sera notre point d’entrée et redirigera le trafic vers les services adaptés en fonction du domaine de nos requêtes. Notez que trois réseaux sont définis dans ce docker-compose, un réseau « frontend » dans lequel sera déployé Traefik ainsi que les services Gravitee, puisque destinés à être accessible de l’extérieur, un réseau « middle » sur lequel sera déployé le service Petstore et un réseau « storage » dans lequel nous retrouverons les systèmes de stockage. Notez que seule la Gateway est déployée sur les trois réseaux, elle sera donc le seul point d’accès au service Petstore.

Avant d’aller plus loin, assurez-vous de définir les domaines am.localhost et apim.localhost dans votre fichier /etc/hosts.

$ sudo vi /etc/hosts
127.0.0.1       localhost
127.0.0.1       apim.localhost
127.0.0.1       am.localhost

Commençons par lancer les différents conteneurs à l’aide d’un docker-compose up et patientons un peu, le temps que les différentes images soient téléchargées.

$ docker-compose up
Starting graviteeio-api-platform_mongodb_1         ... done
Starting graviteeio-api-platform_petstore_1        ... done
Starting graviteeio-api-platform_elasticsearch_1   ... done
Starting graviteeio-api-platform_am_management_1   ... done
Starting graviteeio-api-platform_am_gateway_1      ... done
Starting graviteeio-api-platform_apim_management_1 ... done
Starting graviteeio-api-platform_apim_gateway_1    ... done
Starting graviteeio-api-platform_am_console_1      ... done
Starting graviteeio-api-platform_apim_console_1    ... done
Starting graviteeio-api-platform_apim_portal_1     ... done
Starting graviteeio-api-platform_traefik_1         ... done

Cet environnement de test définit pour le produit APIM trois utilisateurs déclarés de manière statique dans le fichier de configuration. Un utilisateur admin avec les droits administrateur, un utilisateur api1 avec les droits d’édition d’API et enfin, un utilisateur user qui dispose des droits minimaux pour utiliser le produit et souscrire à des API. Dans le cas d’une installation en production, il faudra bien sûr désactiver ces utilisateurs une fois qu’un fournisseur d’identité aura été configuré.

2.2 Premier contact avec la console de gestion

Une fois les services démarrés, connectons-nous sur la console de gestion d’APIM pour déclarer notre API. Pour ce faire, lançons notre navigateur préféré et allons sur https://apim.localhost/console. Dans la mire de login, connectons-nous en tant qu’utilisateur admin en utilisant le mot de passe admin. Une fois connectés, nous arrivons sur la page d’accueil avec un tableau de bord de nos API (voir figure 3).

v-img 003 gravitee-apim-home

Fig. 3 : Écran d’accueil d’APIM où la liste des API de l’utilisateur sera affichée.

Sur la gauche de l’écran se trouve le menu principal avec différentes sections telles que APIs, Applications, Gateways, etc. Pour les besoins de cet article, nous n’utiliserons que le menu APIs.

Passons à la création de notre API. Pour cela, cliquons sur le bouton + au centre de l’écran. Nous avons le choix entre déclarer une API à partir de rien ou importer une définition d’API au format OpenAPI. Pour cet article, créons notre API de zéro en choisissant Create.

Lorsque l’on crée une API, nous avons le choix entre le mode « design studio » et « paths based ». Ce dernier est le mode d’édition historique toujours supporté, mais destiné à disparaître. Le mode « design studio », apparu en version 3.4, propose une meilleure expérience utilisateur et sera le seul mode d’édition des règles à l’avenir.

Plusieurs étapes sont nécessaires à la création d’API. Tout d’abord, il faut nommer notre API, la versionner et lui attribuer un « context path ». Ce paramètre va préfixer l'ensemble des requêtes à destination du service Petstore et permettra à la Gateway de router les demandes (figure 4).

v-img 004 gravitee-apim-create-api-step01

Fig. 4 : Création d’API - première étape, nommer l’API et définir son chemin d’accès.

Après avoir validé cette première étape, il faut définir le point d’accès au service, dans notre cas il s’agit du service Petstore déployé à l’aide de docker-compose dont l’URL est la suivante http://petstore:8080/store (figure 5).

v-img 005 gravitee-apim-create-api-step02

Fig. 5 : Définition du point d’accès au service exposé par notre API.

La troisième étape permet de définir un premier plan. Il s’agit d’une étape facultative lors de la phase de création d’une API, mais il est nécessaire d’avoir au moins un plan pour que l’API soit déployée et démarrée au sein de la Gateway. Nous allons donc créer un plan ne demandant pas d’authentification (type de sécurité positionné à Keyless), mais avec des accès limités au service Petstore, seules les actions de lecture (méthode HTTP GET) seront autorisées avec une fréquence maximale d’une requête par seconde (figure 6).

v-img 006 gravitee-apim-create-api-step03

Fig. 6 : Définition d’un plan sans authentification avec accès limité.

La quatrième étape nous permet d’importer des éléments de documentation. Nous allons passer cette étape dans le cadre de cet article, ce qui nous amène à l’écran de synthèse qui reprend les éléments principaux de l’API. Sur cet écran, il nous est proposé de créer l’API sans la déployer ou de la créer et de la démarrer, ce que nous allons faire afin de tester notre plan sans authentification requise. Une fois validé, nous sommes redirigés vers la page correspondant à notre API (figure 7).

v-img 007 gravitee-apim-api-details

Fig. 7 : Page de détail de l’API « LinuxMagazine - Petstore ».

Cette page va nous permettre d’accéder à différents sous-menus qui nous permettront d’administrer notre API (ajouter des plans, modifier les points d’accès au service Petstore, consulter les journaux d’audits…). Pour le moment, ouvrons un terminal et testons l’accès à l’API Petstore.

jq est un outil en ligne de commande permettant de manipuler du JSON. Dans cet article, il n’est utilisé que pour formater les sorties de l’API, mais il offre beaucoup plus de possibilités, telles que du filtrage ou des transformations.

$ curl -sv -k "https://apim.localhost/petstore/pet/findByStatus?status=available" | jq
...
< HTTP/2 200
< access-control-allow-headers: Content-Type, api_key, Authorization
< access-control-allow-methods: GET, POST, DELETE, PUT
< access-control-allow-origin: *
< content-type: application/json
< date: Sat, 20 Feb 2021 13:52:49 GMT
< server: Jetty(9.2.9.v20150224)
< x-gravitee-request-id: 7b8b68ec-fc6c-4852-8b68-ecfc6c18528e
< x-gravitee-transaction-id: 7b8b68ec-fc6c-4852-8b68-ecfc6c18528e
< content-length: 1148
...
[
  {
    "id": 1,
    "category": {
      "id": 2,
      "name": "Cats"
    },
    "name": "Cat 1",
    "photoUrls": [
      "url1",
      "url2"
    ],
    "tags": [
      {
        "id": 1,
        "name": "tag1"
      },
      {
        "id": 2,
        "name": "tag2"
      }
    ],
    "status": "available"
  },
...

Le retour de cet appel avec des headers commençant par x-gravitee démontre que nous avons bien accès à notre service au travers de la Gateway. Si nous essayons d’exécuter deux requêtes en moins d’une seconde, nous obtiendrons un message d’erreur nous informant que la limite de requêtes a été atteinte, ce qui est conforme à notre configuration.

$ curl -s -k "https://apim.localhost/petstore/pet/findByStatus?status=available" | jq
{
  "message": "Rate limit exceeded ! You reach the limit of 1 requests per 1 seconds",
  "http_status_code": 429
}

Validons maintenant qu’il nous est impossible d’exécuter une demande de modification.

$ curl -s -k -X POST "https://apim.localhost/petstore/pet" -H'Content-Type: application/json' -d '{
>   "id": 42,
>   "category": {
>     "id": 42,
>     "name": "string"
>   },
>   "name": "doggie",
>   "status": "available"
> }'
{"message":"Method not allowed while accessing this resource","http_status_code":405}

Tout fonctionne comme souhaité. Cependant, disposer d’un accès complet à l’API peut s’avérer nécessaire. Nous allons donc créer un nouveau plan sans restriction, sous réserve que l’application soit identifiable. Pour ce faire, allons sur la page de notre API et choisissons le sous-menu Portal, puis Plans. Notre plan sans authentification devrait s’y trouver dans l’état Published (figure 8).

v-img 008 gravitee-apim-plans

Fig. 8 : Liste des plans d’une API.

Pour ajouter un nouveau plan, cliquons sur le bouton + en bas à droite de l’écran. Un premier formulaire apparaît nous permettant de saisir un nom et une description pour notre plan. Quelques options nous sont proposées à cette étape. Activons Auto validate subscription pour accepter automatiquement toutes les demandes de souscriptions à ce plan (figure 9). Si cette option n’est pas activée, toute personne ayant le niveau de droits suffisant sera notifiée à chaque demande de souscription afin de l’accepter ou non. Passons à l’étape suivante en cliquant sur Next.

v-img 009 gravitee-apim-plan-step01

Fig. 9 : Déclaration d’un plan - information générale.

Un nouveau formulaire nous est proposé pour définir le type d’accès à l’API au travers de ce plan. Quatre types d’authentification sont à notre disposition. Sélectionnons le type API Key pour identifier l’application accédant à l’API à l’aide d’une simple clé générée au moment de la souscription. Laissons les autres champs inchangés et passons à l’étape suivante. Cette dernière étape permet de mettre en place des restrictions, comme nous avons pu le faire pour le plan en lecture seule. Pour ce nouveau plan, nous souhaitons donner un accès total à l’API, nous allons donc valider le formulaire sans changement (figure 10).

v-img 010 gravitee-apim-plan-step02

Fig. 10 : Déclaration d’un plan - définition du mode d’accès.

Une fois la création du plan terminée, nous sommes redirigés vers la page des plans à l’état « staging » (figure 11). Une bannière jaune apparaît en haut de la zone principale nous informant que l’API est désynchronisée. En effet, nous venons de créer un nouveau plan qui n’est pas encore connu de la Gateway. Avant de mettre à jour les informations dans la Gateway, passons notre plan à l’état « Published » afin qu’il soit visible du portail des développeurs en cliquant sur l’icône d’upload (le nuage bleu avec une flèche). Cliquons ensuite sur deploy your API depuis la bannière jaune pour synchroniser les informations avec la Gateway.

v-img 011 gravitee-apim-plans-staging

Fig. 11 : Plan non publié et non synchronisé avec la Gateway.

Avant de passer sur le portail développeurs pour souscrire à l’API, assurons-nous que celle-ci est bien publiée et publique, afin de la rendre visible des développeurs sans avoir à gérer les droits d’accès. Pour ce faire, rendons-nous sur la page principale de l’API et cliquons sur Publish the API et Make Public.

2.3 Premier contact avec le portail développeurs

Nous venons de créer notre API et de définir des plans pour limiter ou non l’usage de notre service. Il est maintenant temps d’endosser le rôle d’un développeur d’applications souhaitant utiliser notre API. Pour cela, rendons-nous sur le portail développeurs à l’adresse suivante https://apim.localhost/portal et connectons-nous avec l’utilisateur user dont le mot de passe est password. Une fois connectés, nous pouvons en naviguant dans les différents menus consulter les tableaux de bord de nos applications, consulter le catalogue d’API et y souscrire, gérer nos applications et accéder à la documentation. Rendons-nous dans le catalogue afin de sélectionner l’API qui nous intéresse et y souscrire. Une fois dans le catalogue, sélectionnons le sous-menu All APIs. Les autres sections sont actuellement vides, car nous n’avons pas fait le travail, en tant qu’éditeur d’API, de créer des catégories et d’enrichir le contenu du portail. Une fois l’API sélectionnée, nous accédons à sa description et avons la possibilité de consulter la documentation mise à disposition, ainsi que de prendre contact avec le fournisseur de l’API (figure 12). Nous avons également la possibilité d’y souscrire en cliquant sur le bouton en haut à droite.

v-img 012 gravitee-portal-view-api

Fig. 12 : Visualisation d’une API sur le portail développeurs.

Le processus de souscription se passe en plusieurs étapes. Premièrement, il faut choisir le plan. Dans notre cas, nous avons le choix entre le plan sans authentification qui ne nécessite pas de souscription, et le plan « Premium » pour obtenir une clé nous permettant d’identifier notre application et ainsi de disposer de toutes les fonctionnalités du service proposé (figure 13).

v-img 013 gravitee-portal-subscribe-step01

Fig. 13 : Souscription - choix du plan.

Une fois le plan sélectionné, l’étape suivante permet de choisir l’application pour laquelle la souscription a lieu. Chaque utilisateur dispose d’une application par défaut créée automatiquement (cela est configurable). Sélectionnons cette application et passons à l’étape finale, qui va résumer la demande avant de permettre sa validation. Une fois la souscription validée, nous avons accès à une clé d’API et nous pouvons utiliser le service (figure 14).

v-img 014 gravitee-portal-subscribe step02

Fig. 14 : Souscription réussie pour le plan « Premium » et mise à disposition d’une clé d’API.

Lançons un terminal et validons qu’il nous est possible de faire plus d’une requête par seconde et d’exécuter des requêtes de mise à jour.

$> for i in {1..10}
> do
> curl -I -k -H "X-Gravitee-Api-Key: b1d53213-28f5-47e8-bf1f-9b27fc388eb1" "https://apim.localhost/petstore/pet/findByStatus?status=available"
> done
 
HTTP/2 200
access-control-allow-headers: Content-Type, api_key, Authorization
access-control-allow-methods: GET, POST, DELETE, PUT
access-control-allow-origin: *
content-type: application/json
date: Sat, 20 Feb 2021 14:13:51 GMT
server: Jetty(9.2.9.v20150224)
x-gravitee-request-id: aa43f0c8-c554-48de-83f0-c8c55448de1a
x-gravitee-transaction-id: aa43f0c8-c554-48de-83f0-c8c55448de1a
content-length: 0
 
HTTP/2 200
access-control-allow-headers: Content-Type, api_key, Authorization
access-control-allow-methods: GET, POST, DELETE, PUT
access-control-allow-origin: *
content-type: application/json
date: Sat, 20 Feb 2021 14:13:51 GMT
server: Jetty(9.2.9.v20150224)
x-gravitee-request-id: 4b7746ba-64a1-4ffb-b746-ba64a1effbe8
x-gravitee-transaction-id: 4b7746ba-64a1-4ffb-b746-ba64a1effbe8
content-length: 0
...

Nous ne sommes plus limités sur le nombre de requêtes, essayons maintenant de créer une nouvelle ressource :

$ curl -s -k -XPOST -H "Content-type: application/json" \
> -H "X-Gravitee-Api-Key: b1d53213-28f5-47e8-bf1f-9b27fc388eb1" \
> "https://apim.localhost/petstore/pet/" -d '
> {
>   "id": 0,
>   "category": {
>     "id": 0,
>     "name": "string"
>   },
>   "name": "doggie",
>   "photoUrls": [
>     "string"
>   ],
>   "tags": [
>     {
>       "id": 0,
>       "name": "string"
>     }
>   ],
>   "status": "available"
> }'
{"id":11,"category":{"id":0,"name":"string"},"name":"doggie","photoUrls":["string"],"tags":[{"id":0,"name":"string"}],"status":"available"}

Tout fonctionne comme prévu. Les lecteurs curieux pourront explorer la section Applications du portail afin de découvrir les tableaux de bord et les journaux d’accès permettant d’avoir un aperçu des usages qui sont faits de l’application. Nous venons de créer un plan dont les applications sont identifiées par une clé unique générée à la souscription. Mais attention, rien ne nous garantit que cette clé est utilisée par son propriétaire légitime. Afin de renforcer la sécurité, nous allons décrire dans la section suivante comment générer un token JWT [9] à l’aide du produit AM et utiliser ce token dans un plan.

2.4 Génération d’un token JWT

Avant de définir un nouveau plan prenant en charge un token JWT pour identifier l’application, connectons-nous à Gravitee.io Access Management pour créer un domaine de sécurité et y déclarer une application. Pour cela, rendons-nous sur la console à l’adresse suivante https://am.localhost/login et connectons-nous avec l’utilisateur admin dont le mot de passe par défaut est adminadmin. De la même manière que pour APIM, cet utilisateur n’a pas vocation à perdurer, il n’est là que pour permettre la configuration initiale du service (a minima, il est important de modifier son mot de passe). Une fois connectés, nous allons modifier un paramètre de configuration pour définir le point d’accès à la Gateway. Pour cela, allons dans les Organization settings en bas à gauche, puis dans la section Entrypoints du menu Settings. Éditons le point d’entrée par défaut pour définir le point d’accès suivant : https://am.localhost/auth (figure 15). Ce paramètre correspond à l’URL de base pour les flux d’authentification.

v-img 015 gravitee-am-global-settings

Fig. 15 : Accès aux paramètres globaux.

Une fois ce changement de configuration réalisé, cliquons sur Go back to Access Management et demandons la création d’un domaine de sécurité en cliquant sur Create a Security Domain. Après avoir saisi un nom et validé la création, nous sommes redirigés vers le tableau de bord du domaine. Un encart jaune indique que le domaine n’est pas actif (figure 16). Nous allons le laisser tel quel pour le moment, nous l’activerons une fois la configuration terminée. Sur la gauche de l’écran se trouve le menu associé au domaine où nous pouvons accéder au tableau de bord, gérer les applications et configurer le domaine.

v-img 016 gravitee-am-domain-dashboard

Fig. 16 : Page d’accueil du domaine.

Cliquons sur Settings, un second menu apparaît avec l’ensemble des éléments de configuration du domaine. Dans le cadre ce cet article, nous allons uniquement créer un utilisateur associé à l’« identity provider » par défaut du domaine qui se base sur MongoDB et configurer GitHub comme fournisseur d’identité externe. Pour créer un utilisateur, rendons-nous dans le menu Users de la section User Management et cliquons sur le bouton + en bas à droite, afin de compléter le formulaire (figure 17).

v-img 017 gravitee-am-create-user

Fig. 17 : Formulaire de création d’un utilisateur du domaine de sécurité.

Une fois notre utilisateur créé, configurons GitHub comme fournisseur d’identité en cliquant sur Providers de la section Identities. La liste des fournisseurs d’identité s'affiche et expose MongoDB comme fournisseur par défaut. Cliquons sur le bouton + en bas à droite pour ajouter GitHub. Le formulaire nous demande de saisir le « clientId » et le « clientSecret » fournis par GitHub. Pour le moment, renseignons des données invalides pour ces deux éléments et validons la création. Nous sommes redirigés vers la page de notre provider GitHub (voir figure 18).

v-img 018 gravitee-am-github-identity-provider

Fig. 18 : Configuration de GitHub en tant que fournisseur d’identité.

Sur la droite se trouve l’URL de redirection qu’il faut renseigner au cours de la procédure d’enregistrement de notre application sur GitHub [10] (figure 19). Une fois la procédure terminée, il faudra modifier le « clientId » et le « clientSecret » de notre application avec les valeurs générées par GitHub.

img 019 github-oauth-app

Fig. 19 : Enregistrement de AM dans GitHub.

Maintenant que nous disposons des éléments nécessaires, passons à la déclaration de l’application qui va être autorisée à utiliser ce domaine pour identifier une personne et générer un token d’accès. Pour ce faire, allons dans la section Applications et cliquons sur le bouton +. Le formulaire de création est en deux étapes. Dans un premier temps, nous devons choisir le type d’application afin d’adapter au mieux le flux d’authentification. Choisissons Single Page Application et passons à l’étape suivante. Le formulaire demande ensuite des informations basiques comme le nom de l’application, l’URL de redirection une fois l’authentification réalisée ainsi que les identifiants que l’application devra fournir pour s’authentifier. Pour cet article, une simple page HTML avec du code JavaScript est disponible afin de jouer le rôle d’application cliente. Pour utiliser cette page, l’URL de redirection à saisir est https://am.localhost/client-jwt/ (figure 20).

v-img 020 gravitee-am-create-application

Fig. 20 : Déclaration d’une application dans AM.

Une fois l’application créée, nous sommes redirigés vers une page détaillant les différentes étapes de l’authentification, afin de faciliter la tâche du développeur ayant en charge l’intégration de l’authentification via AM dans son application. Ce sont ces informations qui ont été utilisées pour créer la page référencée par l’URL de redirection et dont le code se trouve dans le dossier client-jwt du repository GitHub. En plus de cette page de documentation, nous pouvons accéder à la liste des différents points d’accès pour communiquer avec la Gateway AM, activer les fournisseurs d’identité proposés par le domaine de sécurité pour notre application, personnaliser les pages de login et les messages de notifications et enfin accéder à la configuration de l’application. Rendons-nous dans l’onglet Identity Providers pour activer l’authentification utilisant MongoDB et GitHub (Figure 21). Une fois cela fait, nous pouvons activer le domaine en cliquant sur le lien de la bannière jaune.

v-img 021 gravitee-am-application-identity-providers

Fig. 21 : Activation des fournisseurs d’identité pour notre application.

Nous pouvons maintenant valider le fonctionnement de notre configuration en utilisant la page de test à l’adresse https://am.localhost/client-jwt/ (figure 22).

img 022 gravitee-am-client-jwt

Fig. 22 : Application cliente.

Après avoir renseigné le domaine, le clientId et le clientSecret, une mire de login s’affiche ainsi qu’un bouton Github. Nous avons la possibilité de nous authentifier avec l’utilisateur john.doe@acme.com créé précédemment grâce à la mire de login ou nous pouvons utiliser notre compte GitHub. Une fois authentifiés, nous sommes redirigés vers l’URL de callback définie au cours de la création de l’application. Lorsque la page de cette URL sera chargée, elle utilisera le paramètre « code » retourné par AM pour demander un jeton d’accès ayant la forme suivante.

{ "access_token" : "eyJraWQiOiJkZWZhdWx0LWdyYXZpdGVlLUFNLWtleSIsImFsZyI6IkhTMjU2In0.eyJzdWIiOiI4YWUzMzg0My1hN2NjLTRhYTEtYTMzOC00M2E3Y2M2YWExMjMiLCJhdWQiOiJwZXRzdG9yZWNsaWVudGlkIiwiZG9tYWluIjoibGludXhtYWdhemluZS1wZXRzdG9yZS1kb21haW4iLCJpc3MiOiJodHRwczpcL1wvYW0ubG9jYWxob3N0XC9hdXRoXC9saW51eG1hZ2F6aW5lLXBldHN0b3JlLWRvbWFpblwvb2lkYyIsImV4cCI6MTYxMzgzOTIxNywiaWF0IjoxNjEzODMyMDE3LCJqdGkiOiJPb3E0NTlacjRKTUFMNWFsSTZ0cVoxRGdOaktoNUhvVVJ0SkN2Mno0ZnM4In0.iXIfEP9L0SzFC7YoPdidpPUNT6QllqyE7MWKqwmth0M", "token_type" : "bearer", "expires_in" : 7199 }

Nous avons donc une configuration AM fonctionnelle. Il nous reste maintenant à retourner sur la console APIM en tant qu’utilisateur admin pour créer un nouveau plan demandant un jeton JWT comme moyen d’authentification. Lors de la création du plan, n’oubliez pas de cocher la validation automatique de la souscription à la première étape, puis complétez l’étape d’authentification en sélectionnant le type JWT et en saisissant HS256 comme signature, GIVEN_KEY en tant que JWKS_Resolver et la clé de signature de AM dans Resolver Parameter (figure 23). La clé est déclarée dans le fichier de configuration de la Gateway AM et est accessible via la commande suivante :

$ docker-compose exec am_gateway cat /opt/graviteeio-am-gateway/config/gravitee.yml | grep "jwt secret"
  secret: s3cR3t4grAv1t3310AMS1g1ingDftK3y

v-img 023 gravitee-apim-plan-jwt

Fig. 23 : Configuration du plan JWT.

Une fois le plan créé, il faudra le publier, puis synchroniser la définition de l’API avec la Gateway. Pour souscrire à ce plan, il nous faut maintenant une application disposant d’un clientId identique à celui créé dans AM. Pour cela, rendons-nous sur le portail développeurs pour créer une nouvelle application en tant qu’utilisateur user. Lors de la seconde étape, renseignons le clientId avec celui défini dans AM et Simple pour le type. Il nous est ensuite possible de souscrire à une API en saisissant le nom de l’API Petstore, puis en sélectionnant le plan JWT. Avant de passer à l’étape suivante, souscrivons au plan et validons la création. Une fois l’application créée, essayons de faire un appel au service avec le jeton JWT généré précédemment.

$ curl -s -k -XPOST -H"Content-type: application/json" \
> -H"Authorization: Bearer eyJraWQiOiJkZWZhdWx0LWdyYXZpdGVlLUFNLWtleSIsImFsZyI6IkhTMjU2In0.eyJzdWIiOiI4YWUzMzg0My1hN2NjLTRhYTEtYTMzOC00M2E3Y2M2YWExMjMiLCJhdWQiOiJwZXRzdG9yZWNsaWVudGlkIiwiZG9tYWluIjoibGludXhtYWdhemluZS1wZXRzdG9yZS1kb21haW4iLCJpc3MiOiJodHRwczpcL1wvYW0ubG9jYWxob3N0XC9hdXRoXC9saW51eG1hZ2F6aW5lLXBldHN0b3JlLWRvbWFpblwvb2lkYyIsImV4cCI6MTYxMzgzOTIxNywiaWF0IjoxNjEzODMyMDE3LCJqdGkiOiJPb3E0NTlacjRKTUFMNWFsSTZ0cVoxRGdOaktoNUhvVVJ0SkN2Mno0ZnM4In0.iXIfEP9L0SzFC7YoPdidpPUNT6QllqyE7MWKqwmth0M" \
>   "https://apim.localhost/petstore/pet/" -d '
> {
>    "id": 0,
>    "category": {
>      "id": 0,
>      "name": "string"
>    },
>    "name": "doggie",
>    "photoUrls": [
>      "string"
>    ],
>    "tags": [
>      {
>        "id": 0,
>        "name": "string"
>      }
>    ],
>    "status": "available"
> }'
{"id":12,"category":{"id":0,"name":"string"},"name":"doggie","photoUrls":["string"],"tags":[{"id":0,"name":"string"}],"status":"available"}

Ça fonctionne! Les lecteurs curieux peuvent se connecter en tant qu’utilisateur admin sur la console de gestion pour aller visiter la section Analytics de l’API. Cela permettra de confirmer que l’API a été accédée au travers de trois différents plans, par deux applications identifiées et une application inconnue qui représente l’usage du plan de type Keyless.

Conclusion

Au travers de cet article, nous avons découvert comment exposer des API grâce à la plate-forme Gravitee.io en proposant des plans d’usage et en sécurisant les accès à l’aide de token JWT. Nous n’avons fait qu’effleurer les possibilités offertes par cette solution d’API Management, en n’utilisant que les éléments de base des deux produits que sont APIM et AM. Il y a beaucoup à dire sur les capacités de cette plate-forme et ces quelques pages vous auront peut-être donné envie de découvrir par vous-même cette solution à la fois simple et puissante.

Références

[1] Dépôt GitHub de WSO2 : https://github.com/wso2

[2] Dépôt GitHub de Gravitee.io : https://github.com/gravitee-io

[3] Environnement de test : https://github.com/leleueri/demo-gravitee

[4] OAuth2 : https://oauth.net/2/

[5] OpenID Connect : https://openid.net/connect/

[6] W3C WebAuthn : https://www.w3.org/TR/webauthn/

[7] Spécifications du service Petstore : https://petstore.swagger.io/

[8] OpenAPI : https://swagger.io/specification/

[9] JSON Web Token : https://tools.ietf.org/html/rfc7519

[10] Création d’une application Oauth sur GitHub : https://docs.github.com/en/free-pro-team@latest/developers/apps/creating-an-oauth-app



Article rédigé par

Les derniers articles Premiums

Les derniers articles Premium

Stubby : protection de votre vie privée via le chiffrement des requêtes DNS

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Depuis les révélations d’Edward Snowden sur l’espionnage de masse des communications sur Internet par la NSA, un effort massif a été fait pour protéger la vie en ligne des internautes. Cet effort s’est principalement concentré sur les outils de communication avec la généralisation de l’usage du chiffrement sur le web (désormais, plus de 90 % des échanges se font en HTTPS) et l’adoption en masse des messageries utilisant des protocoles de chiffrement de bout en bout. Cependant, toutes ces communications, bien que chiffrées, utilisent un protocole qui, lui, n’est pas chiffré par défaut, loin de là : le DNS. Voyons ensemble quels sont les risques que cela induit pour les internautes et comment nous pouvons améliorer la situation.

Surveillez la consommation énergétique de votre code

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Être en mesure de surveiller la consommation énergétique de nos applications est une idée attrayante, qui n'est que trop souvent mise à la marge aujourd'hui. C'est d'ailleurs paradoxal, quand on pense que de plus en plus de voitures permettent de connaître la consommation instantanée et la consommation moyenne du véhicule, mais que nos chers ordinateurs, fleurons de la technologie, ne le permettent pas pour nos applications... Mais c'est aussi une tendance qui s'affirme petit à petit et à laquelle à terme, il devrait être difficile d'échapper. Car même si ce n'est qu'un effet de bord, elle nous amène à créer des programmes plus efficaces, qui sont également moins chers à exécuter.

Donnez une autre dimension à vos logs avec Vector

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Avoir des informations précises et détaillées sur ce qu’il se passe dans une infrastructure, et sur les applications qu'elle héberge est un enjeu critique pour votre business. Cependant, ça demande du temps, temps qu'on préfère parfois se réserver pour d'autres tâches jugées plus prioritaires. Mais qu'un système plante, qu'une application perde les pédales ou qu'une faille de sécurité soit découverte et c'est la panique à bord ! Alors je vous le demande, qui voudrait rester aveugle quand l'observabilité a tout à vous offrir ?

Les listes de lecture

9 article(s) - ajoutée le 01/07/2020
Vous désirez apprendre le langage Python, mais ne savez pas trop par où commencer ? Cette liste de lecture vous permettra de faire vos premiers pas en découvrant l'écosystème de Python et en écrivant de petits scripts.
11 article(s) - ajoutée le 01/07/2020
La base de tout programme effectuant une tâche un tant soit peu complexe est un algorithme, une méthode permettant de manipuler des données pour obtenir un résultat attendu. Dans cette liste, vous pourrez découvrir quelques spécimens d'algorithmes.
10 article(s) - ajoutée le 01/07/2020
À quoi bon se targuer de posséder des pétaoctets de données si l'on est incapable d'analyser ces dernières ? Cette liste vous aidera à "faire parler" vos données.
Voir les 53 listes de lecture

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous