Delen via


Zelfstudie: Een web-API aanroepen vanuit uw Node.js daemon-toepassing

In deze zelfstudie ziet u hoe u uw Node.js daemon-client-app voorbereidt met behulp van de stroom voor het verlenen van open autorisatie (OAuth) 2.0-clientreferenties. Vervolgens configureert u deze om een toegangstoken te verkrijgen voor het aanroepen van een web-API. U bouwt een Node.js toepassing met behulp van MICROSOFT Authentication Library (MSAL) voor Node om het toevoegen van autorisatie aan uw app te vereenvoudigen.

In deze handleiding;

  • App-rollen configureren voor de web-API
  • Machtigingen verlenen aan de daemon-app
  • Maak een Node.js-app in Visual Studio Code en installeer vervolgens afhankelijkheden.
  • Schakel de Node.js-app in om een toegangstoken te verkrijgen voor het aanroepen van een web-API.

Vereiste voorwaarden

  • Registreer een nieuwe client-app in het Microsoft Entra-beheercentrum, geconfigureerd voor accounts in elke organisatiedirectory en persoonlijke Microsoft-accounts. Raadpleeg Een applicatie registreren voor meer details. Noteer de volgende waarden van de Overview pagina van de applicatie voor later gebruik.
    • Applicatie (client) ID
    • Directory-id (huurder)
    • Domeinnaam van map (tenant) (bijvoorbeeld contoso.onmicrosoft.com of contoso.com).
  • Voeg een clientgeheim toe aan de registratie van uw client-app. Gebruik geen clientgeheimen in productie-apps. Gebruik in plaats daarvan certificaten of federatieve referenties. Voor meer informatie, zie referenties toevoegen aan uw toepassing.
  • Een beveiligde web-API die wordt uitgevoerd en gereed is om aanvragen te accepteren. Zorg ervoor dat uw web-API de volgende eindpunten beschikbaar maakt via HTTPS:
    • GET /api/todolist om alle taken op te halen.
    • POST /api/todolist om een TODO toe te voegen.
  • Node.js.
  • Hoewel elke IDE (Integrated Development Environment) die React-toepassingen ondersteunt, kan worden gebruikt, maakt deze zelfstudie gebruik van Visual Studio Code.

App-rollen configureren

Een API moet minimaal één app-rol publiceren voor toepassingen, ook wel toepassingsmachtiginggenoemd, zodat de client-apps zelf een toegangstoken kunnen verkrijgen. Toepassingsmachtigingen zijn het type machtigingen dat API's moeten publiceren wanneer ze clienttoepassingen in staat willen stellen zich als zichzelf te verifiëren en geen gebruikers hoeven aan te melden. Voer de volgende stappen uit om een toepassingsmachtiging te publiceren:

  1. Selecteer op de pagina App-registraties de toepassing die u hebt gemaakt (zoals ciam-ToDoList-api) om de overzichtspagina te openen.

  2. Onder Beheren, selecteer app-rollen.

  3. Selecteer App-rol maken en voer vervolgens de volgende waarden in en selecteer Toepassen om uw wijzigingen op te slaan:

    Vastgoed Waarde
    Weergavenaam ToDoList.Read.All
    Toegestane ledensoorten Applicaties
    Waarde ToDoList.Read.All
    Beschrijving Toestaan dat de app de Takenlijst van elke gebruiker kan lezen met behulp van de TodoListApi
    Wilt u deze app-rol inschakelen? Houd deze ingeschakeld
  4. Selecteer De app-rol opnieuw maken en voer vervolgens de volgende waarden in voor de tweede app-rol en selecteer Toepassen om uw wijzigingen op te slaan:

    Vastgoed Waarde
    Weergavenaam ToDoList.ReadWrite.All
    Toegestane ledensoorten Applicaties
    Waarde ToDoList.ReadWrite.All
    Beschrijving Toestaan dat de app de Takenlijst van elke gebruiker kan lezen en schrijven met behulp van de ToDoListApi
    Wilt u deze app-rol inschakelen? Houd deze ingeschakeld

idtyp-tokenclaim configureren

U kunt de idtyp optionele claim toevoegen om de web-API te helpen bepalen of een token een -app is token of een -app + gebruiker token. Hoewel u een combinatie van scp - en rollenclaims voor hetzelfde doel kunt gebruiken, is het gebruik van de idtyp-claim de eenvoudigste manier om een app-token en een app + gebruikerstoken apart te vertellen. De waarde van deze claim is bijvoorbeeld app wanneer het token een token is dat alleen voor apps geldt.

API-machtigingen verlenen aan de daemon-app

  1. Selecteer op de pagina App-registraties de toepassing die u hebt gemaakt, zoals ciam-client-app.

  2. Selecteer onder Beheren de optie API-machtigingen.

  3. Selecteer onder Geconfigureerde machtigingen de optie Een machtiging toevoegen.

  4. Selecteer de API's die door mijn organisatie worden gebruikt .

  5. Selecteer in de lijst met API's de API, zoals ciam-ToDoList-api.

  6. Selecteer de optie Toepassingsmachtigingen . We selecteren deze optie als de app zich aanmeldt als zichzelf, maar niet namens een gebruiker.

  7. Uit de lijst met machtigingen selecteer je ToDoList.Read.All, ToDoList.ReadWrite.All (gebruik indien nodig het zoekvak).

  8. Selecteer de knop Toestemmingen toevoegen.

  9. Op dit moment hebt u de machtigingen correct toegewezen. Omdat de daemon-app echter niet toestaat dat gebruikers ermee werken, kunnen de gebruikers zelf geen toestemming geven voor deze machtigingen. Om dit probleem op te lossen, moet u als beheerder toestemming geven voor deze machtigingen namens alle gebruikers in de tenant:

    1. Selecteer Verleen beheerderstoestemming voor <uw tenantnaam>, selecteer vervolgens Ja.
    2. Selecteer Vernieuwen en controleer vervolgens of Verleend voor <uw tenantnaam> wordt weergegeven onder Status voor beide machtigingen.

Het Node.js-daemonproject maken

Maak een map om uw Node.js daemon-toepassing te hosten, zoals ciam-call-api-node-daemon:

  1. Navigeer in je terminal naar de map van je Node-daemon-app, zoals cd ciam-call-api-node-daemon, en voer vervolgens npm init -yuit. Met deze opdracht maakt u een standaardbestand package.json voor uw Node.js project. Met deze opdracht maakt u een standaardbestand package.json voor uw Node.js project.

  2. Maak extra mappen en bestanden om de volgende projectstructuur te bereiken:

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

App-afhankelijkheden installeren

Installeer axios, yargs en @azure/msal-node pakketten in de terminal door de volgende opdracht uit te voeren:

npm install axios yargs @azure/msal-node   

MSAL-configuratieobject maken

Open authConfig.js bestand in de code-editor en voeg de volgende code toe:

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

Het msalConfig-object bevat een set configuratieopties die u gebruikt om het gedrag van uw autorisatiestroom aan te passen.

Vervang het volgende in het authConfig.js-bestand:

  • Enter_the_Application_Id_Here met de toepassings-id (client) van de client-daemon-app die u eerder hebt geregistreerd.

  • Enter_the_Tenant_Subdomain_Here en vervang dit door het subdomein Directory (tenant). Als uw primaire tenantdomein bijvoorbeeld is contoso.onmicrosoft.com, gebruikt u contoso. Als u uw tenantnaam niet hebt, leer dan hoe u de details van uw tenant kunt lezen.

  • Enter_the_Client_Secret_Here met de geheime waarde van de clientdaemon-applicatie die u eerder hebt gekopieerd.

  • Enter_the_Web_Api_Application_Id_Here met de toepassings-id (client) van de web-API-app die u eerder hebt gekopieerd.

U ziet dat de scopes eigenschap in de protectedResources variabele de resource-id (toepassings-id-URI) is van de web-API die u hebt geregistreerd als onderdeel van de vereisten. De volledige bereik-URI lijkt op api://Enter_the_Web_Api_Application_Id_Here/.default.

Een toegangstoken verkrijgen

Open auth.js bestand in de code-editor en voeg de volgende code toe:

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

In de code:

  • Bereid het tokenRequest- en apiConfig-object voor. De tokenRequest bevat het bereik waarvoor u een toegangstoken aanvraagt. Het bereik ziet er ongeveer uit als api://Enter_the_Web_Api_Application_Id_Here/.default. Het apiConfig-object bevat het eindpunt voor uw web-API. Meer informatie over OAuth 2.0 client credentials flow.

  • U maakt een vertrouwelijk clientexemplaar aan door het msalConfig-object door te geven aan de constructor van de klasse ConfidentialClientApplication.

    const cca = new msal.ConfidentialClientApplication(msalConfig);
    
  • Vervolgens gebruikt u de functie acquireTokenByClientCredential om een toegangstoken te verkrijgen. U implementeert deze logica in de functie getToken:

    cca.acquireTokenByClientCredential(tokenRequest);
    

Zodra u een toegangstoken hebt verkregen, kunt u doorgaan met het aanroepen van een API.

Een API aanroepen

Open fetch.js bestand in de code-editor en voeg de volgende code toe:

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

In deze code maakt u een aanroep naar de web-API door het toegangstoken door te geven als bearer-token in de aanvraag Authorization header:

 Authorization: `Bearer ${accessToken}`

U gebruikt het toegangstoken dat u eerder hebt verkregen in Een toegangstoken verkrijgen.

Zodra de web-API de aanvraag ontvangt, wordt deze geëvalueerd en wordt vervolgens bepaald dat het een toepassingsaanvraag is. Als het toegangstoken geldig is, retourneert de web-API aangevraagde gegevens. Anders retourneert de API een 401 Unauthorized HTTP-fout.

Uw daemon-app voltooien

Open index.js bestand in de code-editor en voeg de volgende code toe:

#!/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();

Deze code is het toegangspunt voor uw app. U gebruikt de yargs JavaScript opdrachtregelargumentbibliotheek voor het parseren van Node.js apps om interactief een toegangstoken op te halen en vervolgens API aan te roepen. U gebruikt de functies getToken en callApi die u eerder hebt gedefinieerd:

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

Daemon-app en API uitvoeren en testen

Op dit moment bent u klaar om uw client-daemon-app en web-API te testen:

  1. Gebruik de stappen die u hebt geleerd in de zelfstudie Een ASP.NET web-API beveiligen om uw web-API te starten. Uw web-API is nu klaar om clientaanvragen te verwerken. Als u de web-API niet uitvoert op poort 44351 zoals opgegeven in het authConfig.js-bestand, moet u het authConfig.js bestand bijwerken om het juiste poortnummer van de web-API te gebruiken.

  2. Controleer in de terminal of u zich in de projectmap bevindt die uw daemon-Node.js-app bevat, zoals ciam-call-api-node-daemon, en voer vervolgens de volgende opdracht uit:

    node . --op getToDos
    

Als je daemon-app en web-API succesvol worden uitgevoerd, zou je de gegevens die door het web-API-eindpunt todos worden geretourneerd, zoals de volgende variabele JSON-array, in het consolevenster moeten vinden.

{
    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'
}

Volgende stap