Obtenir des jetons dans MSAL Node

Étant donné que MSAL Node prend en charge différents octrois de code d’autorisation, il existe une prise en charge de différentes API publiques par octroi et de la demande correspondante. Cet article vous guidera dans les différentes API publiques disponibles pour chaque flux et le type de requête correspondant. Il est fortement recommandé d’implémenter le flux de code d’autorisation pour votre application.

Flux de code d’autorisation

API publiques

  • getAuthCodeUrl() : cette API constitue la première étape du authorization code grant pour MSAL Node. La requête est de type AuthorizationUrlRequest. L’application reçoit une URL qui peut être utilisée pour générer un authorization code. Cette URL peut être ouverte dans le navigateur de son choix, où l’utilisateur peut saisir ses identifiants, puis être redirigé vers le redirectUri (enregistré lors de l’inscription de l’application) avec un authorization code. Le authorization code peut désormais être échangé contre un(e) token en suivant l’étape suivante. Notez que si le flux de code d’autorisation est effectué pour une application cliente publique, PKCE est recommandé.

  • acquireTokenByCode() : cette API constitue la seconde étape du authorization code grant pour MSAL Node. La requête construite ici doit être de type AuthorizationCodeRequest. L’application a transmis le authorization code reçu dans le cadre de l’étape précédente et l’échange contre un token. Notez que si le flux de code d’autorisation est utilisé pour une application client publique, PKCE est recommandé.


    const authCodeUrlParameters = {
        scopes: ["sample_scope"],
        redirectUri: "your_redirect_uri",
    };

    // get url to sign user in and consent to scopes needed for application
    cca.getAuthCodeUrl(authCodeUrlParameters).then((response) => {
        console.log(response);
    }).catch((error) => console.log(JSON.stringify(error)));

    const tokenRequest = {
        code: "authorization_code",
        redirectUri: "your_redirect_uri",
        scopes: ["sample_scope"],
    };

    // acquire a token by exchanging the code
    cca.acquireTokenByCode(tokenRequest).then((response) => {
        console.log("\nResponse: \n:", response);
    }).catch((error) => {
        console.log(error);
    });

Flux de code de l’appareil

API publiques

  • acquireTokenByDeviceCode() : cette API permet à l’application d’acquérir un jeton avec l’octroi de code d’appareil. La requête est de type DeviceCodeRequest. Cette API obtient un token auprès de l’autorité à l’aide du flux de code d’appareil OAuth 2.0. Ce flux est conçu pour les appareils qui n’ont pas accès à un navigateur ou qui ont des contraintes d’entrée. Le serveur d’autorisation émet un objet DeviceCode avec un code de vérification, un code utilisateur final et l’URI de vérification de l’utilisateur final. L’objet DeviceCode est fourni via un rappel, et l’utilisateur final doit être invité à utiliser un autre appareil pour accéder à l’URI de vérification pour entrer les informations d’identification. Étant donné que le client ne peut pas recevoir de demandes entrantes, il interroge le serveur d’autorisation à plusieurs reprises jusqu’à ce que l’utilisateur final termine l’entrée des informations d’identification.
const msalConfig = {
    auth: {
        clientId: "your_client_id_here",
        authority: "your_authority_here",
    }
};

const pca = new msal.PublicClientApplication(msalConfig);

const deviceCodeRequest = {
    deviceCodeCallback: (response) => (console.log(response.message)),
    scopes: ["user.read"],
};

pca.acquireTokenByDeviceCode(deviceCodeRequest).then((response) => {
    console.log(JSON.stringify(response));
}).catch((error) => {
    console.log(JSON.stringify(error));
});

Flux de jeton d’actualisation

API publiques

  • acquireTokenByRefreshToken : cette API acquiert un jeton en échangeant le jeton d’actualisation fourni pour un nouvel ensemble de jetons. La requête est de type RefreshTokenRequest. Le refresh token n’est jamais renvoyé à l’utilisateur dans une réponse, mais il est accessible depuis le cache utilisateur. Il est recommandé d’utiliser acquireTokenSilent() pour les scénarios non interactifs. Lorsque vous utilisez acquireTokenSilent(), MSAL gère automatiquement la mise en cache et l’actualisation des jetons.
const config = {
    auth: {
        clientId: "your_client_id_here",
        authority: "your_authority_here",
    }
};

const pca = new msal.PublicClientApplication(config);

const refreshTokenRequest = {
    refreshToken: "",
    scopes: ["user.read"],
};

pca.acquireTokenByRefreshToken(refreshTokenRequest).then((response) => {
    console.log(JSON.stringify(response));
}).catch((error) => {
    console.log(JSON.stringify(error));
});

Flux silencieux

API publiques

  • acquireTokenSilent : cette API acquiert un jeton en mode silencieux, au cas où le cache est fourni par l’utilisateur, ou lorsque le cache est créé en précédant cet appel avec tout autre flux interactif (par exemple, flux de code d’autorisation). La requête est de type SilentFlowRequest. L’objet token est acquis en mode silencieux lorsqu’un utilisateur spécifie le compte pour lequel le jeton est demandé.
/**
 * Cache Plugin configuration
 */
const cachePath = "path_to_your_cache_file/msal_cache.json"; // Replace this string with the path to your valid cache file.

const readFromStorage = () => {
    return fs.readFile(cachePath, "utf-8");
};

const writeToStorage = (getMergedState) => {
    return readFromStorage().then(oldFile =>{
        const mergedState = getMergedState(oldFile);
        return fs.writeFile(cachePath, mergedState);
    })
};

const cachePlugin = {
    readFromStorage,
    writeToStorage
};

/**
 * Public Client Application Configuration
 */
const publicClientConfig = {
    auth: {
        clientId: "your_client_id_here",
        authority: "your_authority_here",
        redirectUri: "your_redirectUri_here",
    },
    cache: {
        cachePlugin
    },
};

/** Request Configuration */

const scopes = ["your_scopes"];

const authCodeUrlParameters = {
    scopes: scopes,
    redirectUri: "your_redirectUri_here",
};

const pca = new msal.PublicClientApplication(publicClientConfig);
const msalCacheManager = pca.getCacheManager();
let accounts;

pca.getAuthCodeUrl(authCodeUrlParameters)
    .then((response) => {
        console.log(response);
    }).catch((error) => console.log(JSON.stringify(error)));

const tokenRequest = {
    code: req.query.code,
    redirectUri: "http://localhost:3000/redirect",
    scopes: scopes,
};

pca.acquireTokenByCode(tokenRequest).then((response) => {
    console.log("\nResponse: \n:", response);
    return msalCacheManager.writeToPersistence();
}).catch((error) => {
    console.log(error);
});

// get Accounts
accounts = msalCacheManager.getAllAccounts();

// Build silent request
const silentRequest = {
    account: accounts[0], // You would filter accounts to get the account you want to get tokens for
    scopes: scopes,
};

// Acquire Token Silently to be used in MS Graph call
pca.acquireTokenSilent(silentRequest).then((response) => {
    console.log("\nSuccessful silent token acquisition:\nResponse: \n:", response);
    return msalCacheManager.writeToPersistence();
}).catch((error) => {
        console.log(error);
});

Flux d’informations d’identification client

API publiques

  • acquireTokenByClientCredential : cette API acquiert un jeton à l’aide des informations d’identification de l’application cliente confidentielle pour s’authentifier (au lieu d’emprunter l’identité d’un utilisateur) lors de l’appel d’un autre service web. Dans ce scénario, le client est généralement un service web de niveau intermédiaire, un service démon ou une application web back-end. Pour augmenter le niveau d’assurance, la plateforme d’identités Microsoft autorise également le service d’appel à utiliser un certificat (au lieu d’un secret partagé) comme une information d’identification. La requête est de type ClientCredentialRequest.

Utilisation sécurisée des secrets

Les secrets ne doivent jamais être codés en dur. Le package npm dotenv peut être utilisé pour stocker des secrets dans un fichier .env (situé dans le répertoire racine du projet) qui doit être inclus dans .gitignore pour empêcher les chargements accidentels des secrets.

import "dotenv/config"; // process.env now has the values defined in a .env file

const config = {
    auth: {
        clientId: "your_client_id_here",
        authority: "your_authority_here",
        clientSecret: process.env.clientSecret
    }
};

// Create msal application object
const cca = new msal.ConfidentialClientApplication(config);

// With client credentials flows permissions need to be granted in the portal by a tenant administrator.
// The scope is always in the format "<resource>/.default"
const clientCredentialRequest = {
    scopes: ["https://graph.microsoft.com/.default"], // replace with your resource
};

cca.acquireTokenByClientCredential(clientCredentialRequest).then((response) => {
    console.log("Response: ", response);
}).catch((error) => {
    console.log(JSON.stringify(error));
});

Au nom de Flow

  • acquireTokenOnBehalfOf : cette API implémente le flux on Behalf Of Flow, qui est utilisé lorsqu’une application appelle un service/API web, qui à son tour doit appeler un autre service/API web qui utilise tout autre flux d’authentification (code d’appareil, nom d’utilisateur/mot de passe, etc.). Le jeton d’accès est acquis initialement par l’API web (par l’un des flux d’API web), et l’API web peut ensuite échanger ce jeton pour un autre jeton via OBO. La requête est de type OnBehalfOfRequest

Consultez l’exemple de flux On Behalf Of pour obtenir des instructions d’utilisation :