Drupal 10 : Personnalisation de l’API /oauth/userinfo fournie par Simple OAuth

Introduction

Par défaut, l’API /oauth/userinfo fournie par le module Simple OAuth dans Drupal renvoie uniquement des informations de base, telles que le nom et l’adresse e-mail de l’utilisateur. Toutefois, dans certains cas, il devient nécessaire d’enrichir ces données avec des informations supplémentaires personnalisées pour répondre à des besoins spécifiques. Ce guide, inspiré de la documentation officielle, vous explique comment ajouter des revendications (Claims) OpenID Connect supplémentaires afin d’étendre les données renvoyées par cette API.

Prérequis

Avant de procéder à la configuration, veuillez vous assurer de satisfaire aux conditions suivantes :

Use Case

Nous allons personnaliser l’API /oauth/userinfo pour enrichir les données retournées avec des informations supplémentaires. Nous viserons à inclure dans la réponse l’UUID (identifiant unique de l’utilisateur), la liste des rôles attribués, ainsi que l’URL de l’image de profil. Pour accomplir cela, nous allons utiliser un module personnalisé appelé custom_auth. Ce module sera développé selon les instructions du point 3 des prérequis. Il servira de fondation pour l’ajout de revendications OpenID Connect supplémentaires.

Le processus se déroule en deux étapes principales. Premièrement, nous allons utiliser un hook pour modifier et ajouter des revendications personnalisées. Ensuite, nous configurerons ces revendications dans le fichier web/sites/default/services.yml afin qu’elles soient disponibles dans les réponses de l’API /oauth/userinfo.

Mise en place du service

Nous allons nous concentrer sur l’ajout de revendications (claims) OpenID Connect supplémentaires en utilisant notre module personnalisé custom_auth. Cela nécessite la création d’un service capable de récupérer et de formater les données additionnelles de l’utilisateur, telles que l’UUID, les rôles et l’image de profil.

Le fichier custom_auth.services.yml :

services:
  custom_auth.user_info_service:
    class: 'Drupal\custom_auth\Service\UserInfoService'
    arguments: ['@file_url_generator']

Ce fichier définit un nouveau service appelé custom_auth.user_info_service. Le service fait appel à la classe UserInfoService, que nous allons créer. Le service utilise également @file_url_generator comme argument, un service de Drupal qui permet de générer les URLs complètes pour les fichiers (comme les images de profil des utilisateurs).

Le fichier src/Service/UserInfoService.php :

namespace Drupal\custom_auth\Service;

use Drupal\user\UserInterface;
use Drupal\file\Entity\File;
use Drupal\Core\File\FileUrlGenerator;

/**
 * Service pour personnaliser les informations de l'API /userinfo.
 */
class UserInfoService {

  protected $fileUrlGenerator;

  public function __construct(FileUrlGenerator $file_url_generator) {
    $this->fileUrlGenerator = $file_url_generator;
  }

  public function getCustomClaims(UserInterface $account) {
    $claims = [];
    // Ajoute le UUID de l'utilisateur.
    $claims['uuid'] = $account->uuid();
    // Ajoute les rôles de l'utilisateur.
    $claims['roles'] = $account->getRoles();
    
    // Ajoute l'image de profil si disponible.
    $claims['image'] = NULL;
    if (!$account->get('field_image')->isEmpty()) {
      $image = $account->get('field_image')->entity;
      if ($image instanceof File) {
        $claims['image'] = $this->fileUrlGenerator->generateAbsoluteString($image->getFileUri());
      }
    }

    return $claims;
  }
}

Dans ce fichier, nous utilisons l’interface UserInterface pour interagir avec l’entité utilisateur, File pour gérer les fichiers, et FileUrlGenerator, injecté via le constructeur, pour générer les URL absolues des fichiers. La méthode getCustomClaims accepte un objet utilisateur et renvoie un tableau de “claims” personnalisés. Elle récupère l’UUID de l’utilisateur avec $account->uuid() et les rôles via $account->getRoles(). Si l’utilisateur possède une image de profil (field_image), elle génère l’URL absolue de cette image. Si aucune image n’est disponible, la valeur est définie à NULL.

Utilisation du hook pour ajouter les claims à l’API

Nous utilisons le hook hook_simple_oauth_oidc_claims_alter() pour modifier les revendications (claims) retournées par l’API /userinfo en y ajoutant des informations personnalisées.

Le fichier custom_auth.module :

/**
 * Implements hook_simple_oauth_oidc_claims_alter().
 */
function custom_auth_simple_oauth_oidc_claims_alter(array &$claim_values, array &$context) {
  $account = $context['account'];
  assert($account instanceof \Drupal\user\UserInterface);

  // Appelle le service pour récupérer les claims personnalisés.
  $claims_service = \Drupal::service('custom_auth.user_info_service');
  $custom_claims = $claims_service->getCustomClaims($account);

  // Fusionne les claims personnalisés avec les valeurs existantes.
  $claim_values = array_merge($claim_values, $custom_claims);
}

Ce fichier commence par récupérer l’objet utilisateur à partir du contexte fourni, en s’assurant qu’il s’agit bien d’une instance de \Drupal\user\UserInterface. Ensuite, il appelle le service custom_auth.user_info_service, créé précédemment, pour obtenir les revendications personnalisées via la méthode getCustomClaims. Les nouvelles données sont ensuite fusionnées avec les valeurs existantes de l’API grâce à la fonction PHP array_merge(). Cela permet à l’API /userinfo de retourner à la fois les informations par défaut et les données ajoutées, telles que l’UUID, les rôles, et l’image de profil. Ce processus enrichit ainsi la réponse de l’API de manière dynamique avec des informations supplémentaires spécifiques à l’utilisateur.

Configuration du fichier custom_auth.info.yml

Assurez-vous que le module custom_auth dépend du module Simple OAuth en ajoutant la dépendance simple_oauth dans le fichier custom_auth.info.yml :

name: 'Custom Authentication'
type: module
description: 'Custom Authentication Module: Manage user account activation, email handling, and userinfo API customization'
core_version_requirement: ^10
package: Custom
dependencies:
  - simple_oauth

Configuration du fichier services.yml

Pour permettre à Drupal de savoir quels claims doivent être exposés lors de la génération des tokens OpenID Connect, nous devons ajouter les noms des revendications personnalisées que nous avons définies dans le fichier web/sites/default/services.yml :

services:
  simple_oauth.openid.claims:
    - sub
    - name
    - preferred_username
    - email
    - email_verified
    - profile
    - locale
    - zoneinfo
    - updated_at
    - uuid
    - roles
    - image

Dans cette configuration, nous incluons les revendications standard telles que sub, name, email, et d’autres qui sont présentes par défaut. En outre, nous ajoutons les revendications personnalisées uuid, roles, et image, qui ont été définies via le service custom_auth.user_info_service.

Test

Faites d’abord une requête POST à l’API /oauth/token en utilisant les informations de votre client pour obtenir un token d’accès.

curl --request POST \
  --url http://votre-site-drupal/oauth/token \
  --header 'Content-Type: application/json' \
  --data '{
    "grant_type": "password",
    "client_id": "CLIENT_ID",
    "client_secret": "CLIENT_SECRET",
    "username": "USERNAME",
    "password": "PASSWORD"
  }'

Avec le token d’accès obtenu, effectuez une requête GET à l’API /oauth/userinfo pour récupérer les informations utilisateur enrichies.

curl --request GET \
  --url http://votre-site-drupal/oauth/userinfo \
  --header 'Authorization: Bearer ACCESS_TOKEN'

La réponse de l’API devrait inclure vos nouveaux claims personnalisés, tels que uuid, roles et image.

{
    "sub": "99",
    "name": "[email protected]",
    "preferred_username": "[email protected]",
    "email": "[email protected]",
    "email_verified": true,
    "profile": "https://votre-site-drupal/user/99",
    "locale": "en",
    "zoneinfo": "Europe/Paris",
    "updated_at": 1726647371,
    "uuid": "6a4d2e1b-7f4b-4ef0-9087-2be2c24bd7eb",
    "roles": [
        "authenticated",
        "oauth_role"
    ],
    "image": "https://votre-site-drupal/sites/default/files/2024-09/photo.png"
}

Conclusion

La personnalisation de l’API /oauth/userinfo offre une méthode efficace pour adapter les informations utilisateur selon les besoins spécifiques de votre application. En exploitant la flexibilité de Drupal et le module Simple OAuth, vous pouvez enrichir les données retournées par cette API en ajoutant des informations telles que l’UUID, les rôles et l’image de profil de l’utilisateur. L’utilisation des services et des hooks de Drupal permet une personnalisation fluide et conforme aux standards OpenID Connect, offrant ainsi un meilleur contrôle sur les données exposées et une expérience utilisateur améliorée. Cette approche facilite l’adaptation des informations utilisateur aux exigences de vos applications front-end, garantissant une intégration plus riche et pertinente.

Développeuse fullstack * Plus de publications

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.

Contributeurs

0 0 votes
Évaluation de l'article
guest
2 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
Salla
Salla
13 jours il y a

Merci pour cet article de très grande qualité.

Ingénierie informatique (SSII)

Applize crée des logiciels métiers pour accompagner les entreprises dans la transition vers le zéro papier.


Avez-vous un projet en tête ? Discutons-en.