extensions d’authentification Microsoft pour node

Les extensions d’authentification Microsoft pour Node offrent des mécanismes sécurisés pour que les applications clientes effectuent la sérialisation et la persistance du cache de jetons multiplateformes.

MSAL Node exige que les développeurs implémentent leur propre logique pour conserver le cache de jetons. Les extensions MSAL Node visent à fournir une implémentation de peristence de cache de jetons robuste, sécurisée et configurable sur Windows, Mac et Linux pour les applications clientes publiques (clients de bureau, applications CLI, etc.). Il fournit des mécanismes de chiffrement et d’accès au cache de jetons par plusieurs processus simultanément.

Les plateformes prises en charge sont Windows, Mac et Linux :

  • Windows - DPAPI est utilisé pour le chiffrement.
  • MAC - Le trousseau MAC est utilisé via npm keytar.
  • Linux : LibSecret est utilisé pour le stockage sur « Service secret » via npm keytar.

Code

Création de la couche de persistance

L’API permettant de créer la couche de persistance diffère en fonction de la plateforme que vous ciblez.

Vous pouvez également utiliser l’API createPersistence à partir de PersistenceCreator , car il s’agit d’un wrapper générique et sélectionne la méthode de persistance appropriée en fonction de la plateforme/du système d’exploitation.

const { PublicClientApplication } = require("@azure/msal-node");
const {
  DataProtectionScope,
  PersistenceCreator,
  PersistenceCachePlugin,
} = require("@azure/msal-node-extensions");

const persistence = await PersistenceCreator.createPersistence({
                cachePath: "path/to/cache/file.json",
                dataProtectionScope: DataProtectionScope.CurrentUser,
                serviceName: "test-msal-electron-service",
                accountName: "test-msal-electron-account",
                usePlaintextFileOnLinux: false,
          });
// Use the persistence object to initialize an MSAL PublicClientApplication with cachePlugin
const pca = new PublicClientApplication({
                auth: {
                        clientId: "CLIENT_ID_HERE",
                    },
                cache: {
                        cachePlugin: new PersistenceCachePlugin(persistence);
                    },
                });

Vous pouvez également utiliser les options spécifiques à la plateforme ci-dessous :


const { FilePersistenceWithDataProtection, DataProtectionScope } = require("@azure/msal-node-extensions");
const { PublicClientApplication } = require("@azure/msal-node");

const cachePath = "path/to/cache/file.json";
const dataProtectionScope = DataProtectionScope.CurrentUser;
const optionalEntropy = ""; //specifies password or other additional entropy used to encrypt the data.
const windowsPersistence = await FilePersistenceWithDataProtection.create(cachePath, dataProtectionScope, optionalEntropy);
// Use the persistence object to initialize an MSAL PublicClientApplication with cachePlugin
const pca = new PublicClientApplication({
                auth: {
                        clientId: "CLIENT_ID_HERE",
                    },
                cache: {
                        cachePlugin: new PersistenceCachePlugin(windowsPersistence);
                    },
                });

  • cachePath est le chemin d’accès dans le système de fichiers où le fichier de cache chiffré sera stocké.
  • dataProtectionScope spécifie l’étendue de la protection des données, soit l’utilisateur actuel, soit l’ordinateur local. Vous n’avez pas besoin d’une clé pour protéger ou annuler la protection des données. Si vous définissez l’étendue sur CurrentUser, seules les applications s’exécutant sur vos informations d’identification peuvent annuler la protection des données ; toutefois, cela signifie que toute application s’exécutant sur vos informations d’identification peut accéder aux données protégées. Si vous définissez la portée sur LocalMachine, toute application bénéficiant d’une confiance totale sur l’ordinateur peut supprimer la protection des données, y accéder et les modifier.
  • optionalEntropy spécifie le mot de passe ou une autre entropie supplémentaire utilisée pour chiffrer les données.

Le FilePersistenceWithDataProtection utilise les API Win32 CryptProtectData et CryptUnprotectData. Pour plus d’informations sur dataProtectionScope ou optionalEntropy, reportez-vous à la documentation de ces API.

Toutes les plateformes

Une persistance de fichier non chiffrée, qui fonctionne sur toutes les plateformes, est fournie par commodité, bien qu’elle ne soit pas recommandée.

const { FilePersistence } = require("@azure/msal-node-extensions");

const filePath = "path/to/cache/file.json";
const filePersistence = await FilePersistence.create(filePath, loggerOptions);
// Pass the persistence to msal config's cachePlugin
const pca = new PublicClientApplication({
    auth: {
            clientId: "CLIENT_ID_HERE",
        },
    cache: {
            cachePlugin: new PersistenceCachePlugin(filePersistence);
        },
  });

Si le fichier ou le répertoire n’a pas été créé, FilePersistence.create() créez le fichier et tous les répertoires du chemin d’accès de manière récursive. Cela peut être vu en action dans FilePersistence.ts

Transmission des options de verrouillage au plug-in Cache pour gérer la concurrence

Créez le PersistenceCachePlugin, en transmettant l’objet de persistance créé à l’étape précédente.

const { PersistenceCachePlugin } = require("@azure/msal-node-extensions");

const persistenceCachePlugin = new PersistenceCachePlugin(windowsPersistence); // or any of the other ones.

Pour prendre en charge l’accès simultané par plusieurs processus, les extensions utilisent un verrou basé sur un fichier. Vous pouvez configurer le numéro de nouvelle tentative et le délai de nouvelle tentative pour l’acquisition de verrou via CrossPlatformLockOptions.

const {
  PersistenceCreator,
  PersistenceCachePlugin,
} = require("@azure/msal-node-extensions");

const lockOptions = {
    retryNumber: 100,
    retryDelay: 50
}

const persistence = await PersistenceCreator.createPersistence(persistenceConfiguration);
const persistenceCachePlugin = new PersistenceCachePlugin(persistence, lockOptions); // or any of the other ones
const pca = new PublicClientApplication({
    auth: {
            clientId: "CLIENT_ID_HERE",
        },
    cache: {
            cachePlugin: persistenceCachePlugin
        },
    });

Configuration de PersistenceCachePlugin dans la configuration de MSAL Node PublicClientApplication (avec un exemple)

Pour résumer, une fois que vous avez un PersistenceCachePlugin, qui peut être défini sur le nœud PublicClientApplicationMSAL, en le définissant dans le cadre de l’objet de configuration , comme indiqué ci-dessous.

import { PublicClientApplication } from "@azure/msal-node";

const publicClientConfig = {
    auth: {
        clientId: "",
        authority: "",
    },
    cache: {
        cachePlugin: persistenceCachePlugin
    },
};

const pca = new PublicClientApplication(publicClientConfig);

Exemple (pour l’application de bureau Electron node-js) :

authConfig.js:-

const AAD_ENDPOINT_HOST = "https://login.microsoftonline.com/"; // include the trailing slash
const REDIRECT_URI = "ENTER_REDIRECT_URI";

const cachePath = "path/to/cache/file.json";

/*define persistence config based on the appropriate persistence you are using(e.g- FilePersistenceWithDataProtection, generic PersistenceCreateor, etc)*/

//defining persistence config for PersistenceCreator
const persistenceConfiguration = {
    cachePath,
    dataProtectionScope: DataProtectionScope.CurrentUser,
    serviceName: "test-msal-electron-service",
    accountName: "test-msal-electron-account",
    usePlaintextFileOnLinux: false,
}

  const msalConfig = {
    auth: {
        clientId: "CLIENT_ID_HERE",
        authority: `${AAD_ENDPOINT_HOST}TENANT_ID_HERE`,
    },
    cache: {
        cachePlugin: null // set later in main.js as shown above 
    },
    system: {
        loggerOptions: {
            loggerCallback(loglevel, message, containsPii) {
                console.log(message);
            },
            piiLoggingEnabled: false,
            logLevel: LogLevel.Verbose,
        },
    },
};
...

module.exports = {
  msalConfig: msalConfig,
  protectedResources: protectedResources,
  REDIRECT_URI: REDIRECT_URI,
  persistenceConfiguration
};

Remarque pour les développeurs Electron

Exemple Electron : cet exemple montre comment intégrer la bibliothèque msal-node-extensions dans votre application Electron qui a été empaquetée avec webpack.

Si vous utilisez cette extension pour Electron, vous pouvez rencontrer une erreur similaire à celle-ci :

Uncaught Exception:
Error: The module
"<path-to-project>\node_modules\...\dpapi.node" was compiled against a different Node.js version using NODE_MODULE_VERSION 85. This version of Node.js requires NODE_MODULE_VERSION 80. Please try re-compiling or re-installing the module...."

Cette erreur est probablement due à des différences de version de Node.js entre le projet Electron et l’extension. Cela peut être géré en recréant le package en procédant comme suit :

  • Installez electron-rebuild avec la commande npm i -D electron-rebuild si vous ne l’avez pas déjà installée.
  • Supprimer packages-lock.json de votre projet s’il existe
  • Exécutez ./node_modules/.bin/electron-rebuild

Échantillons

  1. Exemple Electron-webpack pour la persistance
  2. Exemple d’extensions msal-node