Obter tokens no nó MSAL

Como o Nó MSAL dá suporte a várias concessões de código de autorização, há suporte para diferentes APIs públicas por concessão e a solicitação correspondente. Este artigo orientará você pelas diferentes APIs públicas disponíveis para cada fluxo e o tipo de solicitação correspondente. É altamente recomendável que você implemente o fluxo de código de autorização para seu aplicativo.

Fluxo de Código de Autorização

APIs públicas

  • getAuthCodeUrl(): Esta API é a primeira etapa do authorization code grant para o MSAL Node. A solicitação é do tipo AuthorizationUrlRequest. O aplicativo recebe uma URL que pode ser usada para gerar uma authorization code. Essa URL pode ser aberta em um navegador de escolha, onde o usuário pode inserir suas credenciais e será redirecionado de volta para o redirectUri (registrado durante o registro do aplicativo) com um authorization code. Agora, o authorization code pode ser trocado por um token seguindo a etapa abaixo. Observe que, se o fluxo de código de autorização estiver sendo feito para um aplicativo cliente público, o PKCE será recomendado.

  • acquireTokenByCode(): Esta API é a segunda etapa do authorization code grant para o MSAL Node. A solicitação construída aqui deve ser do tipo AuthorizationCodeRequest. O aplicativo passou o authorization code recebido como parte da etapa acima e o troca por um token. Observe que, se o fluxo de código de autorização estiver sendo feito para um aplicativo cliente público, o PKCE é recomendado.


    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);
    });

Fluxo de código do dispositivo

APIs públicas

  • acquireTokenByDeviceCode(): essa API permite que o aplicativo adquira um token com a concessão do Código do Dispositivo. A solicitação é do tipo DeviceCodeRequest. Esta API adquire um token da autoridade usando o fluxo de código de dispositivo OAuth2.0. Esse fluxo foi projetado para dispositivos que não têm acesso a um navegador ou têm restrições de entrada. O servidor de autorização emite um objeto DeviceCode com um código de verificação, um código de usuário final e o URI de verificação do usuário final. O objeto DeviceCode é fornecido por meio de um retorno de chamada e o usuário final deve ser instruído a usar outro dispositivo para navegar até o URI de verificação para inserir credenciais. Como o cliente não pode receber solicitações de entrada, ele sonda o servidor de autorização repetidamente até que o usuário final conclua a entrada de credenciais.
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));
});

Atualizar fluxo de token

APIs públicas

  • acquireTokenByRefreshToken: essa API adquire um token trocando o token de atualização fornecido para um novo conjunto de tokens. A solicitação é do tipo RefreshTokenRequest. O refresh token nunca é retornado ao usuário em resposta, mas pode ser acessado a partir do cache do usuário. É recomendável que você use acquireTokenSilent() para cenários não interativos. Ao usar acquireTokenSilent(), a MSAL manipulará automaticamente o cache e a atualização de tokens.
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));
});

Fluxo Silencioso

APIs públicas

  • acquireTokenSilent: essa API adquire um token silenciosamente, caso o cache seja fornecido pelo usuário ou quando o cache for criado antes dessa chamada com qualquer outro fluxo interativo (por exemplo, fluxo de código de autorização). A solicitação é do tipo SilentFlowRequest. O token valor é adquirido silenciosamente quando um usuário especifica a conta para a qual o token é solicitado.
/**
 * 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);
});

Fluxo de Credenciais do Cliente

APIs públicas

  • acquireTokenByClientCredential: essa API adquire um token usando as credenciais do aplicativo cliente confidencial para autenticar (em vez de representar um usuário) ao chamar outro serviço Web. Nesse cenário, o cliente normalmente é um serviço Web de camada intermediária, um serviço daemon ou um aplicativo Web de back-end. Para um nível mais alto de garantia, a plataforma de identidade da Microsoft também permite que o serviço de chamada use um certificado (em vez de um segredo compartilhado) como uma credencial. A solicitação é do tipo ClientCredentialRequest.

Usando segredos com segurança

Os segredos nunca devem ser codificados. O pacote dotenv npm pode ser usado para armazenar segredos em um arquivo .env (localizado no diretório raiz do projeto) que deve ser incluído no .gitignore para evitar uploads acidentais dos segredos.

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));
});

Em nome da Flow

  • acquireTokenOnBehalfOf: essa API implementa o On Behalf Of Flow, que é usado quando um aplicativo invoca um serviço/API Web, que, por sua vez, precisa chamar outro serviço/API Web que usa qualquer outro fluxo de autenticação (código do dispositivo, nome de usuário/senha etc). O token de acesso é adquirido pela API Web inicialmente (por qualquer um dos fluxos de API Web) e a API Web pode trocar esse token por outro token via OBO. A solicitação é do tipo OnBehalfOfRequest

Consulte o exemplo do fluxo On Behalf Of para ver as instruções de uso: