Partilhar via


Tutorial: Chamar uma API da Web a partir do seu aplicativo daemon Node.js

Este tutorial demonstra como preparar seu aplicativo cliente Node.js daemon usando o fluxo de concessão de credenciais do cliente Open Authorization (OAuth) 2.0 e, em seguida, configurá-lo para adquirir um token de acesso para chamar uma API da Web. Você criará um aplicativo Node.js usando a Biblioteca de Autenticação da Microsoft (MSAL) para o Nó para simplificar a adição de autorização ao seu aplicativo.

Neste tutorial:

  • Configurar funções de aplicativo para a API da Web
  • Conceder permissões ao aplicativo daemon
  • Crie um aplicativo Node.js no Visual Studio Code e instale dependências.
  • Habilite o aplicativo Node.js para adquirir um token de acesso para chamar uma API da Web.

Pré-requisitos

  • Registre um novo aplicativo cliente no centro de administração do Microsoft Entra, configurado para Contas em qualquer diretório organizacional e contas pessoais da Microsoft. Consulte Registar uma candidatura para obter mais detalhes. Registre os seguintes valores na página Visão geral do aplicativo para uso posterior:
    • ID da aplicação (cliente)
    • ID do diretório (inquilino)
    • Nome de domínio do diretório (locatário) (por exemplo, contoso.onmicrosoft.com ou contoso.com).
  • Adicione um segredo do cliente ao registro do aplicativo cliente. Não use segredos de cliente em aplicativos de produção. Em vez disso, use certificados ou credenciais federadas. Para obter mais informações, consulte Adicionar credenciais ao seu aplicativo.
  • Uma API da Web protegida que está em execução e pronta para aceitar solicitações. Certifique-se de que a sua API Web exponha os seguintes endpoints via HTTPS:
    • GET /api/todolist para obter todas as tarefas.
    • POST /api/todolist adicionar uma tarefa pendente.
  • Node.js.
  • Embora qualquer ambiente de desenvolvimento integrado (IDE) que ofereça suporte a aplicativos React possa ser usado, este tutorial usa o Visual Studio Code.

Configurar funções do aplicativo

Uma API precisa publicar um mínimo de uma função de aplicativo para aplicativos, também chamada de permissão de aplicativo, para que os aplicativos cliente obtenham um token de acesso como eles mesmos. As permissões de aplicativo são o tipo de permissões que as APIs devem publicar quando desejam permitir que os aplicativos cliente se autentiquem como si mesmos com sucesso e não precisem que os usuários façam login. Para publicar uma permissão de aplicativo, execute estas etapas:

  1. Na página Registros de aplicativos , selecione o aplicativo que você criou (como ciam-ToDoList-api) para abrir sua página Visão geral .

  2. Em Gerir, selecione Funções da aplicação.

  3. Selecione Criar função de aplicativo, insira os seguintes valores e selecione Aplicar para salvar as alterações:

    Propriedade Valor
    Nome de exibição ToDoList.Read.All
    Tipos de membros permitidos Aplicações
    Valor ToDoList.Read.All
    Descrição Permita que o aplicativo leia a lista de ToDo de cada usuário usando o 'TodoListApi'
    Deseja ativar esta função da aplicação? Mantenha-o verificado
  4. Selecione Criar função de aplicativo novamente e, em seguida, insira os seguintes valores para a segunda função de aplicativo e selecione Aplicar para salvar as alterações:

    Propriedade Valor
    Nome de exibição ToDoList.ReadWrite.All
    Tipos de membros permitidos Aplicações
    Valor ToDoList.ReadWrite.All
    Descrição Permita que o aplicativo leia e escreva a lista de ToDo de cada usuário usando o 'ToDoListApi'
    Deseja ativar esta função da aplicação? Mantenha-o verificado

Configurar a declaração do token idtyp

Você pode adicionar a declaração opcional idtyp para ajudar a API da web a determinar se um token é um token de aplicativo ou um token de aplicativo + usuário . Embora você possa usar uma combinação de declarações scp e roles para a mesma finalidade, usar a declaração idtyp é a maneira mais fácil de diferenciar um token de aplicativo e um token de aplicativo + usuário. Por exemplo, o valor desta declaração é app quando o token é um token apenas de app.

Conceder permissões de API para o aplicativo daemon

  1. Na página Registros de aplicativos , selecione o aplicativo que você criou, como ciam-client-app.

  2. Em Gerenciar, selecione Permissões de API.

  3. Em Permissões configuradas, selecione Adicionar uma permissão.

  4. Selecione a guia APIs que minha organização usa .

  5. Na lista de APIs, selecione a API, como ciam-ToDoList-api.

  6. Selecione a opção Permissões do aplicativo . Selecionamos esta opção quando a aplicação inicia a sessão como ela própria, mas não em nome de um utilizador.

  7. Na lista de permissões, selecione TodoList.Read.All, ToDoList.ReadWrite.All (use a caixa de pesquisa, se necessário).

  8. Selecione o botão Adicionar permissões .

  9. Neste ponto, você atribuiu as permissões corretamente. No entanto, como o aplicativo daemon não permite que os usuários interajam com ele, os próprios usuários não podem consentir com essas permissões. Para resolver esse problema, você, como administrador, deve consentir com essas permissões em nome de todos os usuários no locatário:

    1. Selecione Conceder consentimento de administrador para <o nome> do seu inquilino e, em seguida, selecione Sim.
    2. Selecione Atualizar, e em seguida, verifique se Concedido para <o nome do seu locatário> aparece em Status para ambas as permissões.

Criar o projeto de daemon Node.js

Crie uma pasta para hospedar seu aplicativo daemon Node.js, como ciam-call-api-node-daemon:

  1. No terminal, altere o diretório para a pasta do aplicativo Node daemon, como cd ciam-call-api-node-daemone, em seguida, execute npm init -y. Este comando cria um arquivo de package.json padrão para seu projeto Node.js. Este comando cria um arquivo de package.json padrão para seu projeto Node.js.

  2. Crie pastas e arquivos adicionais para obter a seguinte estrutura de projeto:

        ciam-call-api-node-daemon/
        ├── auth.js
        └── authConfig.js
        └── fetch.js
        └── index.js 
        └── package.json
    

Instalar dependências de aplicativos

No seu terminal, instale axios, yargs e @azure/msal-node pacotes executando o seguinte comando:

npm install axios yargs @azure/msal-node   

Criar objeto de configuração MSAL

No editor de códigos, abra authConfig.js arquivo e adicione o seguinte código:

require('dotenv').config();

/**
 * Configuration object to be passed to MSAL instance on creation.
 * For a full list of MSAL Node configuration parameters, visit:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/configuration.md
 */    
const msalConfig = {
    auth: {
        clientId: process.env.CLIENT_ID || 'Enter_the_Application_Id_Here', // 'Application (client) ID' of app registration in Azure portal - this value is a GUID
        authority: process.env.AUTHORITY || 'https://Enter_the_Tenant_Subdomain_Here.ciamlogin.com/', // Replace "Enter_the_Tenant_Subdomain_Here" with your tenant subdomain
        clientSecret: process.env.CLIENT_SECRET || 'Enter_the_Client_Secret_Here', // Client secret generated from the app 
    },
    system: {
        loggerOptions: {
            loggerCallback(loglevel, message, containsPii) {
                console.log(message);
            },
            piiLoggingEnabled: false,
            logLevel: 'Info',
        },
    },
};    
const protectedResources = {
    apiToDoList: {
        endpoint: process.env.API_ENDPOINT || 'https://localhost:44351/api/todolist',
        scopes: [process.env.SCOPES || 'api://Enter_the_Web_Api_Application_Id_Here'],
    },
};

module.exports = {
    msalConfig,
    protectedResources,
};

O objeto msalConfig contém um conjunto de opções de configuração que você usa para personalizar o comportamento do seu fluxo de autorização.

No arquivo authConfig.js , substitua:

  • Enter_the_Application_Id_Here com o ID da aplicação (cliente) da aplicação cliente daemon que registou anteriormente.

  • Enter_the_Tenant_Subdomain_Here e substitua-o pelo subdomínio Directory (tenant). Por exemplo, se o domínio principal do arrendatário for contoso.onmicrosoft.com, utilize contoso. Se não tiver o nome do inquilino, saiba como ler os detalhes do inquilino.

  • Enter_the_Client_Secret_Here com o valor secreto do aplicativo daemon cliente copiado anteriormente.

  • Enter_the_Web_Api_Application_Id_Here com o ID da aplicação (cliente) da aplicação de API da Web que copiou anteriormente.

Observe que a propriedade scopes na variável protectedResources é o identificador de recurso (URI de ID do aplicativo) da API Web que registou como parte dos pré-requisitos. O URI de escopo completo é semelhante ao api://Enter_the_Web_Api_Application_Id_Here/.default.

Adquira um token de acesso

No editor de códigos, abra auth.js arquivo e adicione o seguinte código:

const msal = require('@azure/msal-node');
const { msalConfig, protectedResources } = require('./authConfig');
/**
 * With client credentials flows permissions need to be granted in the portal by a tenant administrator.
 * The scope is always in the format '<resource-appId-uri>/.default'. For more, visit:
 * https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
 */
const tokenRequest = {
    scopes: [`${protectedResources.apiToDoList.scopes}/.default`],
};

const apiConfig = {
    uri: protectedResources.apiToDoList.endpoint,
};

/**
 * Initialize a confidential client application. For more info, visit:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/initialize-confidential-client-application.md
 */
const cca = new msal.ConfidentialClientApplication(msalConfig);
/**
 * Acquires token with client credentials.
 * @param {object} tokenRequest
 */
async function getToken(tokenRequest) {
    return await cca.acquireTokenByClientCredential(tokenRequest);
}

module.exports = {
    apiConfig: apiConfig,
    tokenRequest: tokenRequest,
    getToken: getToken,
};

No código:

  • Prepare o objeto tokenRequest e apiConfig. O tokenRequest contém o escopo para o qual você solicita um token de acesso. O escopo é algo como api://Enter_the_Web_Api_Application_Id_Here/.default. O objeto apiConfig contém o ponto de extremidade para a sua API da Web. Saiba mais sobre o fluxo de credenciais do cliente OAuth 2.0.

  • Você cria uma instância de cliente confidencial passando o msalConfig objeto para o construtor da classe ConfidentialClientApplication .

    const cca = new msal.ConfidentialClientApplication(msalConfig);
    
  • Em seguida, use a função acquireTokenByClientCredential para adquirir um token de acesso. Você implementa essa lógica na função getToken:

    cca.acquireTokenByClientCredential(tokenRequest);
    

Depois de adquirir um token de acesso, você pode continuar a chamar uma API.

Chamar uma API

No editor de códigos, abra fetch.js arquivo e adicione o seguinte código:

const axios = require('axios');

/**
 * Calls the endpoint with authorization bearer token.
 * @param {string} endpoint
 * @param {string} accessToken 
 */
async function callApi(endpoint, accessToken) {

    const options = {
        headers: {
            Authorization: `Bearer ${accessToken}`
        }
    };

    console.log('request made to web API at: ' + new Date().toString());

    try {
        const response = await axios.get(endpoint, options);
        return response.data;
    } catch (error) {
        console.log(error)
        return error;
    }
};

module.exports = {
    callApi: callApi
};

Neste código, faz-se uma chamada à API web, passando o token de acesso como um "bearer token" no cabeçalho da solicitação Authorization.

 Authorization: `Bearer ${accessToken}`

Você utiliza o token de acesso que adquiriu anteriormente em Adquirir um token de acesso.

Depois que a API da Web recebe a solicitação, ela a avalia e determina que se trata de uma solicitação de aplicativo. Se o token de acesso for válido, a API da Web retornará os dados solicitados. Caso contrário, a API retornará um erro HTTP 401 Unauthorized.

Finalize seu aplicativo daemon

No editor de códigos, abra index.js arquivo e adicione o seguinte código:

#!/usr/bin/env node

// read in env settings

require('dotenv').config();

const yargs = require('yargs');
const fetch = require('./fetch');
const auth = require('./auth');

const options = yargs
    .usage('Usage: --op <operation_name>')
    .option('op', { alias: 'operation', describe: 'operation name', type: 'string', demandOption: true })
    .argv;

async function main() {
    console.log(`You have selected: ${options.op}`);

    switch (yargs.argv['op']) {
        case 'getToDos':
            try {
                const authResponse = await auth.getToken(auth.tokenRequest);
                const todos = await fetch.callApi(auth.apiConfig.uri, authResponse.accessToken);                
            } catch (error) {
                console.log(error);
            }

            break;
        default:
            console.log('Select an operation first');
            break;
    }
};

main();

Esse código é o ponto de entrada para seu aplicativo. Use a biblioteca de análise de argumentos de linha de comando yargs JavaScript para aplicações Node.js a fim de buscar interativamente um token de acesso e, em seguida, chamar a API. Use as funções getToken e callApi definidas anteriormente:

const authResponse = await auth.getToken(auth.tokenRequest);
const todos = await fetch.callApi(auth.apiConfig.uri, authResponse.accessToken);                

Executar e testar o aplicativo daemon e a API

Neste ponto, você está pronto para testar seu aplicativo daemon cliente e sua API da Web:

  1. Use as etapas aprendidas no tutorial Proteger uma API da Web ASP.NET para iniciar sua API da Web. Sua API da Web agora está pronta para atender às solicitações dos clientes. Se não executar a sua API Web na porta 44351, conforme especificado no arquivo authConfig.js, atualize o arquivo authConfig.js para usar o número de porta correto da API Web.

  2. No seu terminal, certifique-se de que está na pasta do projeto que contém o seu daemon Node.js aplicação, como o ciam-call-api-node-daemone, em seguida, execute o seguinte comando:

    node . --op getToDos
    

Se o aplicativo daemon e a API da Web forem executados com êxito, você deverá encontrar os dados retornados pela variável todos de ponto de extremidade da API da Web, semelhante à seguinte matriz JSON, na janela do console:

{
    id: 1,
    owner: '3e8....-db63-43a2-a767-5d7db...',
    description: 'Pick up grocery'
},
{
    id: 2,
    owner: 'c3cc....-c4ec-4531-a197-cb919ed.....',
    description: 'Finish invoice report'
},
{
    id: 3,
    owner: 'a35e....-3b8a-4632-8c4f-ffb840d.....',
    description: 'Water plants'
}

Próximo passo