gerer-ses-utilisateurs-avec-keycloak-et-nodejs

Qu’est-ce que Keycloak ?

Keycloak est un logiciel open source permettant de mettre en place une méthode d’authentification unique.

Il permet d’avoir un unique compte donnant l’accès à tous les services d’une entreprise via le protocole OpenID ou SAML.

Configuration de Keycloak (Client Scopes, permissions)

Afin de configurer votre Client (celui qu’utilisera l’application Node), rendez-vous sur la console de Keycloak.
Suite à cela allez dans la section : Clients

Vous pourrez ensuite en créer un nouveau, pour cela renseignez seulement son Client ID et laissez tous les autres paramètres par défaut :

Enregistrez puis modifiez la partie « Access Type » pour la configurer sur « confidential » :

Une fois fait, vous devez renseigner une URL de redirection. Vous pouvez utiliser celle de votre application web. Ensuite, vous pouvez enregistrer.

Une fois enregistré, la section « Credentials » apparait, vous pourrez trouver le « Client Secret » pour s’authentifier à l’API de Keycloak, notez le et ne le divulguez pas !

Votre configuration est terminée, passons au code !

Installation du paquet Keycloak

Afin d’installer le paquet Keycloak, vous pouvez utiliser les gestionnaires de paquets NodeJs de votre choix (Yarn, Npm)

$ yarn add @keycloak/keycloak-admin-client
$ npm install @keycloak/keycloak-admin-client 

Authentification

Afin de s’authentifier depuis notre application à Keycloak, nous allons alors utiliser les identifiants clients générés au préalable. Pour cela, importez le paquet Keycloak admin client :

const KcAdminClient = require("@keycloak/keycloak-admin-client").default;

Suite à cela, nous allons créer l’objet Client et le configurer de cette manière :

const Client = new KcAdminClient();

Client.setConfig({
  realmName: process.env.KC_REALM,
  baseUrl: process.env.KC_BASE_URL,
});

const credentials = {
  grantType: 'client_credentials',
  clientId: process.env.KC_CLIENT_ID,
  clientSecret: process.env.KC_CLIENT_SECRET,
};

realName correspond au realm que vous utiliserez.

baseUrl est l’url de votre Keycloak

Il est important d’utiliser des variables d’environnement afin d’éviter de publier ou de rendre public les données sensibles, ainsi que de faire un programme modulaire, pouvant s’adapter à différents clients Keycloak !

Une fois les paramètres de connexions renseignés, nous allons procéder à la connexion.
Lors de chacune des authentifications à Keycloak, celui-ci nous retourne un jeton d’authentification « access_token » et un jeton de renouvellement « refresh_token » permettant de renouveler votre jeton d’authentification une fois celui-ci expiré.
Pour cela, il suffira de rappeler la fonction d’authentification à intervalle régulier.

setInterval(async () => await Client.auth(credentials), 60 * 1000); // Renouvellement toutes les minutes

L’authentification étant faite, nous pouvons maintenant faire des requêtes pour gérer nos utilisateurs sur Keycloak. Pour cela, il est nécessaire d’exporter l’objet Keycloak afin qu’il puisse être utilisé facilement sur l’ensemble du projet.

Le fichier keycloak.js contient donc la configuration et la connexion via Keycloak :

const KcAdminClient = require("@keycloak/keycloak-admin-client").default;

const Client = new KcAdminClient();

Client.setConfig({
  realmName: process.env.KC_REALM,
  baseUrl: process.env.KC_BASE_URL,
});

const credentials = {
  grantType: 'client_credentials',
  clientId: process.env.KC_CLIENT_ID,
  clientSecret: process.env.KC_CLIENT_SECRET,
};
Client.auth(credentials);
setInterval(async () => await Client.auth(credentials), 58 * 1000); // 58 seconds

exports.Client = Client;

Afin de réutiliser l’objet keycloak n’importe où dans le projet, il suffira de l’importer de cette manière :

const Client = require("/path/file/keycloak.js");

//variable Client is now linked to the object

Gestion de vos utilisateurs

Chaque utilisateur sur Keycloak nécessite de renseigner des informations de base telles que :

  • Email, afin de différencier les utilisateurs
  • Username, afin de donner un nom à l’utilisateur

Dans l’exemple ci-dessous, nous rajouterons un prénom ainsi qu’un nom de famille à la création d’un utilisateur :

const Keycloak = require("/path/to/file/keycloak");

// Create user in Keycloak
async function createUser(username, email, firstName, lastName) {
    const check_username = await Keycloak.Client.users.find({username: username});
    if (check_username.length > 0) {
      console.error("Username exists.");
      return (-1);
    }
    await Keycloak.Client.users.create({
      username: username,
      firstName: firstName,
      lastName; lastName,
      email: email
    });
    console.log("Success")
    return (0);
}

Dans cette configuration, nous vérifierons au préalable qu’aucun utilisateur n’existe avec ces informations pour ne pas créer de doublons. Suite à cela, la fonction Create permet de créer un nouvel utilisateur.

Lister les utilisateurs via l’API de Keycloak

Maintenant que des utilisateurs ont été crées, nous pouvons les lister.
Pour cela, nous réutiliserons la fonction find(), sans filtre afin d’obtenir tous les utilisateurs :

async function list() {
  const users = await Keycloak.Client.users.find();
  console.log("Liste des utilisateurs :")
  console.table(users)
}

Modifier un utilisateur via l’API de Keycloak

Si vous souhaitez modifier un utilisateur, vous devez spécifier son identifiant afin de ne pas altérer les autres. C’est pour cela que la modification d’un utilisateur se fera seulement par identifiant. Chaque utilisateur a son propre identifiant lui permettant de le différencier des autres (a contrario de son nom et prénom qui peuvent avoir des homonymes).

L’identifiant de l’utilisateur s’obtient après avoir appelé la fonction find() qui retournera toutes les informations de celui-ci, y compris son identifiant unique.

Dans le cas ci dessous, nous souhaitons modifier l’email de l’utilisateur :

async function update(id, email) {
    await Keycloak.Client.users.update({ id: id },{email: email});
}

Supprimer un utilisateur via l’API de Keycloak

La suppression de l’utilisateur est similaire à sa modification, la différence étant que l’utilisateur ainsi que ses données sont supprimées.

async function delete_user(id) {
  await Keycloak.Client.users.del({ id: req.params.id });
}

ATTENTION: Si lors d’une modification ou suppression vous n’utilisez pas de filtres, tous les utilisateurs seront modifiés ou même supprimés, ce qui est pratique pour modifier un grand nombre d’utilisateurs mais dangereux dans le cas de la suppression.

N’hésitez pas à faire appel à notre service de DevOps à la demande pour la mise en place de Keycloak

Partager cet article

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.