Introduction
Dans un environnement où les API jouent un rôle central dans l’intégration d’applications, il est essentiel de garantir leur configuration correcte et sécurisée. Cet article explique comment mettre en place et sécuriser une API dans Drupal 10 en utilisant les modules JSON:API, JSON Extras, Simple OAuth, et Consumers. Vous apprendrez à configurer une API sécurisée pour les utilisateurs avec des permissions spécifiques, permettant un accès contrôlé aux données exposées via JSON.
Prérequis
Avant de commencer la configuration, vous devez disposer d’un environnement Drupal fonctionnel. Pour des instructions détaillées sur l’installation de Drupal, veuillez vous référer à Comment installer Drupal dans un conteneur docker
Use case
Nous mettrons en œuvre la fonctionnalité de sécurisation d’une API pour les utilisateurs ayant le rôle “OAUTH_ROLE“. D’abord, ce rôle sera créé avec les permissions nécessaires. Les modules Consumers et Simple OAuth sont essentiels pour mettre en place un système d’authentification OAuth sécurisé dans Drupal. Simple OAuth gère l’émission des jetons d’accès pour authentifier les utilisateurs, tandis que Consumers permet de restreindre l’accès à l’API en fonction des permissions définies. Cette combinaison offre une solution robuste pour sécuriser les échanges de données, garantissant que seuls les utilisateurs autorisés peuvent accéder aux endpoints JSON de l’API. Après avoir généré un token OAuth pour un utilisateur “OAUTH_ROLE“, nous testerons l’accès aux endpoints JSON sécurisés, en confirmant que seuls les utilisateurs avec le bon token peuvent accéder aux données.
Installation et activation des modules nécessaires
Pour commencer la configuration de votre API sécurisée, la première étape est d’installer et d’activer les modules indispensables.
- JSON:API : Permet d’exposer les entités Drupal via une API RESTful.
- JSON:API Extras : Fournit des configurations supplémentaires pour JSON.
- JSON:API Permission Access : Ajoute un contrôle d’accès aux routes JSON, simplifiant la gestion des permissions sans configuration manuelle pour chaque entité ou champ.
- Simple OAuth : Fournit une méthode d’authentification OAuth 2.0 pour les API RESTful.
- Consumers : Permet de configurer des permissions spécifiques pour les applications consommant l’API, en contrôlant quels utilisateurs ou rôles peuvent accéder aux différentes routes de l’API.
Vous pouvez installer ces modules en utilisant Composer, qui est l’outil de gestion des dépendances pour PHP, permettant de télécharger et de gérer les modules Drupal et leurs dépendances. Voici les commandes Composer pour installer les modules nécessaires :
composer require 'drupal/jsonapi_extras:^3.24'
composer require 'drupal/jsonapi_permission_access:^1.0'
composer require 'drupal/simple_oauth:^5.2'
composer require 'drupal/consumers:^1.19'
Étant donné que JSON:API fait partie du noyau (depuis la version 8.7.x), vous n’avez pas besoin de l’installer mais juste de l’activer.
Vous pouvez activer ces modules soit directement depuis l’interface d’administration de Drupal sous Extend, soit en utilisant la ligne de commande Drush avec la commande suivante
drush en jsonapi jsonapi_extras simple_oauth consumers -y
Configuration de JSON:API et JSON:API Extras
Pour configurer JSON:API, accédez à /admin/config/services/jsonapi pour spécifier si chaque endpoint doit être en lecture seule ou autoriser toutes les opérations CRUD (Create, Read, Update, Delete)
Ensuite, accédez à la page de configuration de JSON:API Extras à l’adresse /admin/config/services/jsonapi/extras
. Dans cette section, vous pouvez modifier le préfixe des routes en remplaçant /jsonapi
par /api
dans le champ « Path prefix ».
Sous la section « Resource overrides », une liste des entités disponibles sera affichée. Vous pouvez personnaliser les routes en modifiant par exemple /api/node/article
en /api/article
, définir quels champs doivent être exposés, utiliser des alias pour les champs (comme tags
au lieu de field_tags
), et améliorer la sortie de l’API. Pour apporter ces modifications, cliquez sur « Overwrite » et ajustez les paramètres de l’entité selon vos besoins.
Configuration de Simple OAuth
Pour configurer Simple OAuth, commencez par définir les durées d’expiration des tokens. Accédez à /admin/config/people/simple_oauth
et configurez les paramètres suivants :
- Access Token Expiration Time : Définissez le temps d’expiration par défaut pour les nouveaux tokens d’accès, exprimé en secondes (par exemple, 1209600 secondes).
- Authorization Code Expiration Time : Définissez le temps d’expiration par défaut pour les nouveaux codes d’autorisation, également en secondes. Utilisez la même valeur que pour les tokens d’accès si vous n’êtes pas certain.
- Refresh Token Expiration Time : Définissez le temps d’expiration par défaut pour les tokens de rafraîchissement, en secondes.
- Token Batch Size : Indiquez le nombre de tokens expirés à supprimer par lot lors de l’exécution de cron (mettez à 0 pour désactiver).
Ensuite, faites défiler jusqu’en bas de la page, cliquez sur « Generate keys », et suivez les instructions pour définir un chemin de stockage sécurisé pour les clés, par exemple ../config/jwt
.
Assurez-vous d’avoir les droits d’écriture sur ce répertoire ; sinon, exécutez la commande suivante pour ajuster les permissions :
chmod -R 777 ../config/jwt
Création et configuration du consumer
- Ajouter un rôle : accédez à
admin/people/roles
; cliquez sur « Add role » et nommez-le par exemple «OAUTH_ROLE
». - Configurer les permissions du rôle : accédez à
admin/people/permissions
et donnez au rôle « OAUTH_ROLE » les permissions que vous jugez nécessaire y compris ‘Access JSON:API Routes
‘ (sans cette permission spécifique ajoutée par le module JSON:API Permission Access , les utilisateurs, à l’exception des administrateurs, ne pourront pas accéder aux données des endpoints JSON). - Ajouter un consumer : accédez à
admin/config/services/consumer
; cliquez sur « Add consumer » et remplissez les informations nécessaires (label, client ID, client Secret etc.). Puis dans la section ‘Scopes’ associez le consumer au rôle ‘OAUTH_ROLE
’.
Pour cet exemple, le client_id est QOf6alZN9a9ZB2bLG0o9qVPeNKCAeMB6UANmcSdXie4
et le client_secret
est oauth
.
Génération et récupération du token
Pour obtenir un token d’accès et un token de rafraîchissement, commencez par créer un utilisateur avec le rôle approprié. Accédez à /admin/people/create
, créez un utilisateur (par exemple [email protected]
/ John12345678
) , et assignez-lui le rôle « OAUTH_ROLE
».
Ensuite, générez un token en effectuant une requête POST à l’endpoint /oauth/token
. Utilisez la commande curl suivante :
curl --request POST \
--url http://your-drupal-site/oauth/token \
--header 'content-type: application/json' \
--data '{ "grant_type": "password",
"client_id": "QOf6alZN9a9ZB2bLG0o9qVPeNKCAeMB6UANmcSdXie4",
"client_secret": "oauth",
"username": "[email protected]",
"password": "John12345678"
}'
Le retour de cette requête inclura un access_token
et un refresh_token
. Le access_token
permet d’accéder aux endpoints JSON sécurisés, tandis que le refresh_token
est utilisé pour obtenir un nouveau access_token
lorsque le précédent expire.
Pour accéder aux endpoints protégés, comme /api/article
, utilisez le access_token
dans les en-têtes de vos requêtes :
curl --request GET \
--url http://your-drupal-site/api/article \
--header 'authorization: Bearer YOUR_ACCESS_TOKEN'
Assurez-vous que le token reçu est valide et permet l’accès aux données selon les permissions définies.
API userinfo
Après l’obtention d’un access token, vous pouvez utiliser l’API /oauth/userinfo
pour récupérer les informations du profil de l’utilisateur associé au token. Cette API est très pratique pour valider l’identité de l’utilisateur ou obtenir des informations spécifiques sans avoir à interroger manuellement les entités utilisateur dans Drupal. Assurez-vous d’inclure l’access token dans l’en-tête Authorization pour garantir que l’utilisateur est correctement authentifié.
Pour personnaliser les informations renvoyées par l’API userinfo, vous pouvez consulter l’article sur la Personnalisation de l’API /oauth/userinfo fournie par Simple OAuth
Utilisation du Refresh Token
Après l’expiration du access token, il est possible d’obtenir un nouveau token en utilisant le refresh token sans devoir fournir à nouveau les informations de connexion de l’utilisateur. Cette fonctionnalité est gérée via le même endpoint /oauth/token
, mais avec des paramètres différents. voici un exemple de requête pour rafraîchir le token :
grant_type=refresh_token
: Indique que la requête doit utiliser le refresh token.refresh_token
: Le refresh token obtenu lors de la génération du premier token d’accès.client_id
etclient_secret
: Les informations du consumer configuré.
La requête retourne un nouveau access token et un nouveau refresh token. Ce nouveau access token est ensuite utilisé pour accéder aux endpoints sécurisés.
Il est important de noter que pour toutes les requêtes autres que GET dans Drupal, un token CSRF (Cross-Site Request Forgery) est obligatoire pour sécuriser les opérations. Ce token CSRF peut être obtenu via l’API GET /session/token
et doit être ajouté dans les en-têtes des requêtes sous la forme suivante : X-CSRF-Token: [votre_token_csrf].
Les tests pour ces fonctionnalités ont été réalisés en utilisant Apidog, un outil efficace pour gérer et tester les API.
Problèmes liés à la version 5.2 de Simple OAuth
La version 5.2 du module Simple OAuth présente des limitations notables et des failles de sécurité qui peuvent affecter l’authentification dans les environnements découplés utilisant Drupal. Voici les principaux problèmes identifiés :
- Génération de tokens pour les utilisateurs bloqués : un des problèmes majeurs de cette version est la possibilité pour des utilisateurs avec un statut “bloqué” d’obtenir un token OAuth. Même si ces tokens ne permettent pas de réaliser des actions, car toute tentative d’utilisation retourne une erreur “Not Authorized”, la simple génération d’un token pour ces utilisateurs est problématique. Cela crée de la confusion et pourrait potentiellement introduire des vulnérabilités. En pratique, seuls les utilisateurs “activés” devraient pouvoir obtenir un token d’accès.
- Attribution incorrecte des rôles dans les tokens d’accès : un autre problème concerne la gestion des rôles dans les tokens OAuth. Lors de l’authentification via Simple OAuth, tous les rôles associés au Consumer sont inclus dans le token généré, même si certains rôles ne sont pas attribués à l’utilisateur en question. Par exemple, un utilisateur ayant uniquement le rôle “auteur” peut recevoir un token contenant également les rôles “banquier” ou “cordonnier”, simplement parce que ces rôles sont définis dans le Consumer. Cela pose un sérieux problème de sécurité, car un utilisateur pourrait recevoir des permissions supplémentaires non autorisées. Ce problème est bien documenté sur Drupal.org dans ce ticket.
Améliorations dans Simple OAuth 6.x (version bêta)
La version 6.x de Simple OAuth, actuellement en phase bêta, apporte des correctifs et des améliorations significatives pour résoudre ces problèmes et renforcer la sécurité de l’authentification.
- Blocage de la génération de tokens pour les utilisateurs non activés : dans cette nouvelle version, le problème de la génération de tokens pour les utilisateurs bloqués a été corrigé. Désormais, seuls les utilisateurs “activés” peuvent obtenir un token d’accès, ce qui garantit une meilleure cohérence et sécurité dans le processus d’authentification. Les utilisateurs bloqués sont totalement exclus du mécanisme d’authentification, ce qui évite la génération de tokens inutiles ou trompeurs.
- Correction de l’attribution des rôles dans les tokens : la version 6.x améliore également la manière dont les rôles sont attribués dans les tokens OAuth. Contrairement à la version 5.2, où tous les rôles du Consumer étaient inclus dans le token, cette nouvelle version s’assure que seuls les rôles effectivement attribués à l’utilisateur dans Drupal sont présents dans le token d’accès. Cette modification renforce la sécurité en empêchant les utilisateurs de recevoir des permissions qu’ils ne devraient pas avoir.
- Dépréciation du grant-type
password
: une autre modification importante dans la version 6.x est la dépréciation du grant-typepassword
pour des raisons de sécurité. Seuls les grant-typesauthorization_code
,client_credentials
, etrefresh_token
sont désormais disponibles, ce qui renforce la protection des données utilisateurs.
Mise à jour vers la version 6.x
Si vous souhaitez passer de la version 5.2 à la version 6.x, voici les étapes à suivre pour une mise à jour correcte :
composer require 'drupal/simple_oauth:^6.0@beta'
composer update
drush updb
Ces commandes mettront à jour le module Simple OAuth vers la version 6.x tout en appliquant les mises à jour de la base de données nécessaires.
L’installation et la configuration de la version 6.x de Simple OAuth suivent globalement le même processus que la version 5.2, mais quelques différences importantes doivent être prises en compte. Avant de créer un Consumer, il est désormais nécessaire de configurer les rôles qui lui seront associés dans le sous-menu “Scope” accessible via le chemin /admin/config/people/simple_oauth/oauth2_scope/dynamic
.
De plus, la configuration d’un Consumer exige maintenant que le champ Redirect URLs
soit rempli. Il s’agit d’un champ obligatoire dans lequel il est nécessaire de spécifier au moins une URL valide. Cette URL sera utilisée pour rediriger les utilisateurs après le processus d’authentification, assurant ainsi une gestion fluide et sécurisée de la redirection après connexion.
Le module Simple OAuth Password Grant
Ce module Simple OAuth Password Grant réimplémente le grant-type password
à partir de la version 6.0.x de Simple OAuth, permettant son utilisation dans des scénarios découplés sécurisés où le backend et le frontend sont contrôlés par la même entité. Bien que ce grant soit déprécié dans OAuth2 pour des raisons de sécurité, notamment dans les cas où une application partage ses informations avec des tiers (car l’envoi direct des identifiants utilisateur via une requête POST peut exposer ces données sensibles), il reste pertinent lorsque les données ne sont pas partagées avec des tiers. L’installation se fait via Composer avec la commande suivante :
composer require 'drupal/simple_oauth_password_grant:^1.0'
Une fois le module installé et activé, vous devez activer le grant-type password
dans les paramètres du Consumer.
Lorsque le grant password
est activé, vous pouvez obtenir un token d’accès en envoyant une requête POST à /oauth/token
avec le payload suivant :
{
"grant_type": "password",
"client_id": "__your-client-id__",
"client_secret": "__your-client-secret__",
"username": "drupal_username_or_email",
"password": "drupal_password"
}
Pour plus d’informations sur la simplification de l’authentification OAuth 2.0, vous pouvez consulter l’article sur Simplification de l’Authentification OAuth 2.0 avec un Middleware Personnalisé.
Conclusion
La configuration et la sécurisation d’une API dans Drupal 10 nécessitent une attention particulière aux détails, depuis l’installation des modules indispensables jusqu’à la gestion des tokens d’accès. En suivant les étapes décrites, vous pouvez créer une API robuste et sécurisée, avec des permissions spécifiques pour les utilisateurs et des mécanismes de protection comme l’authentification OAuth2 et les tokens CSRF. Assurez-vous de configurer correctement les rôles et permissions pour contrôler l’accès aux données sensibles, et de tester vos endpoints pour garantir que seuls les utilisateurs autorisés peuvent interagir avec l’API. Cette approche garantit non seulement la fonctionnalité de votre API, mais aussi sa sécurité, un aspect essentiel dans tout environnement d’intégration moderne.
Développeuse fullstack spécialisée en Systèmes d'Information Répartis , diplômée de la section informatique de la Faculté des Sciences et Techniques (FST) de l'UCAD. Je relève avec passion des défis complexes, avec une forte capacité d'adaptation et un engagement pour la collaboration en équipe. Toujours avide d'apprendre, je vise à créer un impact positif et à promouvoir l'excellence organisationnelle dans chaque projet.