Freigeben über


Tutorial: Aufrufen einer Web-API aus Ihrer Node.js-Daemonanwendung

Dieses Tutorial veranschaulicht, wie Sie Ihre Node.js-Daemonclient-App mithilfe des Flows für die Zuweisung von Clientanmeldeinformationen in OAuth 2.0 (Open Authorization) vorbereiten und anschließend so konfigurieren, dass sie ein Zugriffstoken für das Aufrufen einer Web-API abruft. Sie erstellen eine Node.js Anwendung mit Microsoft Authentication Library (MSAL) für Node , um das Hinzufügen von Autorisierung zu Ihrer App zu vereinfachen.

In diesem Tutorial:

  • Konfigurieren von App-Rollen für die Web-API
  • Erteilen von Berechtigungen für die Daemon-App
  • Erstellen Sie eine Node.js App in Visual Studio Code, und installieren Sie dann Abhängigkeiten.
  • Aktivieren Sie die Node.js-App, um ein Zugriffstoken zum Aufrufen einer Web-API abzurufen.

Voraussetzungen

  • Registrieren Sie eine neue Client-App im Microsoft Entra Admin Center, die für Konten in allen Organisationsverzeichnissen und persönlichen Microsoft-Konten konfiguriert ist. Weitere Informationen finden Sie unter Registrieren einer Anwendung . Notieren Sie die folgenden Werte auf der Anwendungsübersichtsseite für die spätere Verwendung:
    • Anwendungs-ID (Client)
    • Verzeichnis-ID (Mandant)
    • Verzeichnisdomänenname (Mandant) (z. B. contoso.onmicrosoft.com oder contoso.com).
  • Fügen Sie Ihrer Client-App-Registrierung einen geheimen Clientschlüssel hinzu. Verwenden Sie keine Client-Geheimnisse in Produktionsanwendungen. Verwenden Sie stattdessen Zertifikate oder Verbundanmeldeinformationen. Weitere Informationen finden Sie unter Hinzufügen von Anmeldeinformationen zu Ihrer Anwendung.
  • Eine geschützte Web-API, die ausgeführt wird und bereit ist, Anforderungen anzunehmen. Stellen Sie sicher, dass Ihre Web-API die folgenden Endpunkte über HTTPS verfügbar macht:
    • GET /api/todolist, um alle Aufgaben abzurufen.
    • POST /api/todolist, um eine Aufgabe hinzuzufügen.
  • Node.js
  • Sie können jede integrierte Entwicklungsumgebung (IDE) verwenden, die React-Anwendungen unterstützt. In diesem Tutorial wird Visual Studio Code verwendet.

Konfigurieren von App-Rollen

Eine API muss mindestens eine App-Rolle für Anwendungen veröffentlichen, die auch als Anwendungsberechtigung bezeichnet wird, damit die Client-Apps ein Zugriffstoken in ihrem eigenen Namen abrufen können. Anwendungsberechtigungen sind der Typ von Berechtigungen, die APIs veröffentlichen sollten, wenn sie Clientanwendungen eine erfolgreiche Authentifizierung als sie selbst ermöglichen wollen und keine Benutzerinnen bzw. Benutzer anmelden müssen. Befolgen Sie die folgenden Schritte, um eine Anwendungsberechtigung zu veröffentlichen:

  1. Wählen Sie auf der Seite App-Registrierungen die von Ihnen erstellte Anwendung (z. B. ciam-ToDoList-api) aus, um ihre Seite Übersicht zu öffnen.

  2. Wählen Sie unter Verwalten die Option Anwendungsrollen aus.

  3. Wählen Sie App-Rolle erstellen aus, und geben Sie die folgenden Werte ein. Wählen Sie dann Anwenden aus, um Ihre Änderungen zu speichern:

    Eigentum Wert
    Anzeigename ToDoListe.Lesen.Alle
    Zulässige Mitgliedstypen Anwendungen
    Wert ToDoListe.Lesen.Alle
    BESCHREIBUNG Geben Sie der App Lesezugriff auf die ToDo-Liste aller Benutzer*innen mithilfe von „ToDoListApi“.
    Möchten Sie diese App-Rolle aktivieren? Aktiviert lassen
  4. Wählen Sie erneut App-Rolle erstellen aus, und geben Sie die folgenden Werte für die zweite App-Rolle ein. Wählen Sie dann Anwenden aus, um Ihre Änderungen zu speichern:

    Eigentum Wert
    Anzeigename ToDoList.ReadWrite.All
    Zulässige Mitgliedstypen Anwendungen
    Wert ToDoList.ReadWrite.All
    BESCHREIBUNG Geben Sie der App Lese- und Schreibzugriff auf die ToDo-Liste eines jeden Benutzers mit Hilfe der „ToDoListApi“.
    Möchten Sie diese App-Rolle aktivieren? Aktiviert lassen

Konfigurieren des Tokenanspruchs „idtyp“

Sie können den optionalen idtyp-Anspruch hinzufügen, um der Web-API zu helfen, zu bestimmen, ob es sich bei einem Token um ein App-Token oder ein App + Benutzertoken handelt. Obwohl Sie eine Kombination aus Scp - und Rollenansprüchen für denselben Zweck verwenden können, ist die Verwendung des idtyp-Anspruchs die einfachste Möglichkeit, ein App-Token und ein App + Benutzertoken voneinander zu unterscheiden. Der Wert dieses Anspruchs ist beispielsweise app, wenn das Token ein reines App-Token ist.

Erteilen von API-Berechtigungen für die Daemonanwendung

  1. Wählen Sie auf der Seite Anwendungsregistrierungen die von Ihnen erstellte Anwendung (z. B. ciam-client-app) aus.

  2. Wählen Sie unter Verwalten die Option API-Berechtigungen aus.

  3. Wählen Sie unter Konfigurierte Berechtigungen die Option Berechtigung hinzufügen aus.

  4. Wählen Sie die Registerkarte Von meiner Organisation verwendete APIs aus.

  5. Wählen Sie in der Liste der APIs die API aus, z. B. ciam-ToDoList-api.

  6. Wählen Sie die Option Anwendungsberechtigungen aus. Wir wählen diese Option aus, weil sich die App nicht im Namen eines Benutzers oder einer Benutzerin, sondern selbst anmeldet.

  7. Wählen Sie in der Berechtigungsliste TodoList.Read.All, ToDoList.ReadWrite.All aus (verwenden Sie bei Bedarf das Suchfeld).

  8. Wählen Sie die Schaltfläche Berechtigungen hinzufügen aus.

  9. An diesem Punkt haben Sie die Berechtigungen ordnungsgemäß zugewiesen. Da die Daemon-App jedoch keine Interaktion mit Benutzerinnen oder Benutzern zulässt, können die Benutzerinnen und Benutzer selbst diesen Berechtigungen nicht zustimmen. Um dieses Problem zu beheben, müssen Sie als Administrator im Namen aller Benutzer im Mandanten diesen Berechtigungen zustimmen:

    1. Wählen Sie Administratorzustimmung für <Name Ihres Mandanten> erteilen und dann Ja aus.
    2. Wählen Sie Aktualisieren aus, und vergewissern Sie sich, dass für beide Berechtigungen unter < der Status Erteilt für >Name Ihres Mandanten angezeigt wird.

Erstellen des Node.js-Daemonprojekts

Erstellen Sie einen Ordner zum Hosten Ihrer Node.js-Daemonanwendung, z. B. ciam-call-api-node-daemon:

  1. Wechseln Sie in Ihrem Terminal in das Verzeichnis Ihres Node.js-Daemonanwendungsordners, z. B. cd ciam-call-api-node-daemon, und führen Sie dann npm init -y aus. Dieser Befehl erstellt eine Standarddatei namens package.json für Ihr Node.js-Projekt. Mit diesem Befehl wird eine package.json-Standarddatei für Ihr Node.js-Projekt erstellt.

  2. Erstellen Sie weitere Ordner und Dateien, um die folgende Projektstruktur zu erstellen:

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

Installieren von App-Abhängigkeiten

Installieren Sie in Ihrem Terminal die Pakete axios, yargs und @azure/msal-node, indem Sie die folgenden Befehle ausführen:

npm install axios yargs @azure/msal-node   

Erstellen des MSAL-Konfigurationsobjekts

Öffnen Sie in Ihrem Code-Editor die Datei authConfig.js, und fügen Sie dann den folgenden Code hinzu:

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

Das msalConfig-Objekt enthält eine Reihe von Konfigurationsoptionen, die von Ihnen zum Anpassen des Verhaltens Ihres Autorisierungsflows verwendet werden.

Ersetzen Sie Folgendes in Ihrer authConfig.js-Datei:

  • Enter_the_Application_Id_Here mit der Anwendungs-ID (Client-ID) der zuvor von Ihnen registrierten Client-Daemon-App.

  • Enter_the_Tenant_Subdomain_Here und ersetzen Sie es durch die Verzeichnis-(Mandanten-)Unterdomäne. Wenn Ihre primäre Mandantendomäne z. B. contoso.onmicrosoft.comist, verwenden Sie contoso. Wenn Sie Ihren Mandantennamen nicht kennen, lesen Sie die Informationen unter Abrufen der Details des Mandanten.

  • Enter_the_Client_Secret_Here mit dem Wert des geheimen Clientschlüssels der Clientdaemon-App, den Sie zuvor kopiert haben.

  • Enter_the_Web_Api_Application_Id_Here durch die Anwendungs-ID (Client-ID) der Web-API-Anwendung, die Sie zuvor kopiert haben.

Beachten Sie, dass die scopes Eigenschaft in der protectedResources Variablen der Ressourcenbezeichner (Anwendungs-ID-URI) der Web-API ist, die Sie als Teil der Voraussetzungen registriert haben. Der vollständige URI des Bereichs sieht ähnlich aus wie api://Enter_the_Web_Api_Application_Id_Here/.default.

Abrufen eines Zugriffstokens

Öffnen Sie in Ihrem Code-Editor die Datei auth.js, und fügen Sie dann den folgenden Code hinzu:

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

Im Code:

  • Bereiten Sie das tokenRequest- und apiConfig-Objekt vor. Die tokenRequest enthält den Bereich, für den Sie ein Zugriffstoken anfordern. Der Bereich sieht etwa so aus wie api://Enter_the_Web_Api_Application_Id_Here/.default. Das apiConfig-Objekt enthält den Endpunkt zu Ihrer Web-API. Erfahren Sie mehr über den OAuth 2.0-Clientanmeldeinformationsflow.

  • Sie erstellen eine vertrauliche Clientinstanz, indem Sie das msalConfig-Objekt an den Konstruktor der ConfidentialClientApplication-Klasse übergeben.

    const cca = new msal.ConfidentialClientApplication(msalConfig);
    
  • Anschließend verwenden Sie die Funktion acquireTokenByClientCredential, um ein Zugriffstoken abzurufen. Sie implementieren diese Logik in der getToken-Funktion:

    cca.acquireTokenByClientCredential(tokenRequest);
    

Nachdem Sie ein Zugriffstoken abgerufen haben, können Sie mit dem Aufrufen einer API fortfahren.

Aufrufen einer API

Öffnen Sie in Ihrem Code-Editor die Datei fetch.js, und fügen Sie dann den folgenden Code hinzu:

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 diesem Code rufen Sie die Web-API auf, indem Sie das Zugriffstoken als Bearertoken im Header der Anforderung Authorization übergeben:

 Authorization: `Bearer ${accessToken}`

Sie verwenden das Zugriffstoken, das Sie zuvor in Abrufen eines Zugriffstokens abgerufen haben.

Sobald die Web-API die Anforderung empfangen hat, wird sie ausgewertet und dann festgestellt, dass es sich um eine Anwendungsanforderung handelt. Wenn das Zugriffstoken gültig ist, gibt die Web-API angeforderte Daten zurück. Andernfalls gibt die API einen 401 Unauthorized-HTTP-Fehler zurück.

Abschließen Ihrer Daemon-App

Öffnen Sie in Ihrem Code-Editor die Datei index.js, und fügen Sie dann den folgenden Code hinzu:

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

Dieser Code ist der Einstiegspunkt für Ihre App. Sie verwenden die yargs JavaScript-Befehlszeilenargumentanalysebibliothek für Node.js-Apps, um interaktiv ein Zugriffstoken abzurufen, und rufen dann die API auf. Sie verwenden die Funktionen getToken und callApi, die Sie zuvor definiert haben:

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

Ausführen und Testen der Daemon-App und API

An diesem Punkt können Sie Ihre Clientdaemon-App und Web-API testen:

  1. Führen Sie die Schritte aus, die Sie im Lernprogramm zum Sichern einer ASP.NET Web-API gelernt haben, um Ihre Web-API zu starten. Ihre Web-API ist jetzt bereit, Clientanforderungen zu bedienen. Wenn Sie Ihre Web-API nicht an Port 44351 ausführen, wie in der Datei authConfig.js angegeben, stellen Sie sicher, dass Sie die Datei authConfig.js aktualisieren, um die korrekte Portnummer Ihrer Web-API zu verwenden.

  2. Vergewissern Sie sich in Ihrem Terminal, dass Sie sich in dem Projektordner befinden, der Ihre Node.js-Daemon-App enthält, z. B. ciam-call-api-node-daemon, und führen Sie dann den folgenden Befehl aus:

    node . --op getToDos
    

Wenn Ihre Daemon-App und Ihre Web-API erfolgreich ausgeführt werden, sollten im Konsolenfenster die von der Variablen todos des Web-API-Endpunkts zurückgegebenen Daten ähnlich dem folgenden JSON-Array angezeigt werden:

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

Nächster Schritt