Självstudie: Flödesautentisering från App Service via serverdels-API till Microsoft Graph

Lär dig hur du skapar och konfigurerar en serverdelsapptjänst för att acceptera en klientdelsapps användarautentiseringsuppgifter och byt sedan ut autentiseringsuppgifterna mot en nedströms Azure-tjänst. Detta gör att en användare kan logga in på en klientdelsapptjänst, skicka sina autentiseringsuppgifter till en serverdelsapptjänst och sedan komma åt en Azure-tjänst med samma identitet.

I den här tutorialen lär du dig följande:

  • Konfigurera backend-autentiseringsappen för att tillhandahålla en token med rättighetsomfång till Azure-tjänsten som mottar data nedströms
  • Använd JavaScript-kod för att byta ut den inloggade användarens åtkomsttoken mot en ny token för underordnade tjänster.
  • Använd JavaScript-kod för att komma åt underordnad tjänst.

Förutsättningar

Slutför den föregående självstudien , Åtkomst till Microsoft Graph från en skyddad JavaScript-app som användare, innan du påbörjar den här självstudien, men ta inte bort resurserna i slutet av självstudien. Den här handledningen förutsätter att du har de två apptjänsterna och deras motsvarande autentiseringsappar.

I den föregående självstudien användes Azure Cloud Shell som gränssnitt för Azure CLI. Den här självstudien fortsätter det användandet.

Arkitektur

Självstudien visar hur man skickar användarens inloggningsuppgifter som tillhandahålls av frontend-appen till backend-appen och sedan vidare till en Azure-tjänst. I den här självstudien är den underordnade tjänsten Microsoft Graph. Användarens autentiseringsuppgifter används för att hämta sin profil från Microsoft Graph.

Arkitekturbild av App Service som ansluter till Microsoft Graph på uppdrag av en inloggad användare.

Autentiseringsflöde för en användare för att hämta Microsoft Graph-information i den här arkitekturen:

Föregående självstudie :

  1. Logga in användare på en frontendtjänst som konfigurerats för att använda Active Directory som identitetsleverantör.
  2. Klientdelens App Service skickar användarens token till serverdelens App Service.
  3. Backend-applikationen är säkrad så att frontenden kan göra en API-begäran. Användarens åtkomsttoken är avsett för backend-API:ets klienter och har omfattningen user_impersonation.
  4. Registreringen av bakgrundsappen har redan Microsoft Graph med omfånget User.Read. Detta läggs som standard till i alla appregistreringar.
  5. I slutet av den föregående självstudien returnerades en falsk profil till frontend-applikationen eftersom Graph inte var ansluten.

Den här handledningen utökar arkitekturen.

  1. Bevilja administratörsmedgivande för att kringgå skärmen med användarmedgivande för serverdelsappen.
  2. Ändra programkoden för att konvertera åtkomsttoken som skickas från klientdelsappen till en åtkomsttoken med nödvändig behörighet för Microsoft Graph.
  3. Ange kod för att serverdelsappen ska byta token mot en ny token med rätt omfång för en nedströms Azure-tjänst, till exempel Microsoft Graph.
  4. Ange kod för att serverdelsappen ska använda ny token för att komma åt nedströmstjänsten som den aktuella autentiserade användaren.
  5. Återdistribuera serverdelsappen med az webapp up.
  6. I slutet av den här självstudien returneras en verklig profil till frontend-appen eftersom Graph är anslutet.

Den här guiden omfattar inte

  • Ändra frontend-appen från föregående självstudie.
  • Ändra omfångsbehörigheten för autentiseringsappen för backend eftersom User.Read läggs till som standard i alla autentiseringsappar.

I den föregående självstudien, när användaren loggade in på frontend-applikationen, visades ett popup-fönster där användarens samtycke efterfrågades.

För att kunna läsa användarprofilen från Microsoft Graph i den här självstudien måste backend-appen byta ut den inloggade användarens åtkomsttoken mot en ny åtkomsttoken med de behörigheter som krävs för Microsoft Graph. Eftersom användaren inte är direkt ansluten till serverdelsappen kan de inte komma åt medgivandeskärmen interaktivt. Du måste kringgå detta genom att konfigurera serverdelsappens appregistrering i Microsoft Entra-ID för att ge administratörsmedgivande. Det här är en inställningsändring som vanligtvis utförs av en Active Directory-administratör.

  1. Öppna Azure-portalen och sök efter din backend-App Service.

  2. Leta reda på avsnittet Inställningar –> autentisering .

  3. Välj identitetsprovidern för att gå till autentiseringsappen.

  4. I autentiseringsappen väljer du Hantera –> API-behörigheter.

  5. Välj Bevilja administratörsmedgivande för Standardkatalog.

    Skärmbild av azure-portalens autentiseringsapp med knappen administratörsmedgivande markerad.

  6. I popup-fönstret väljer du Ja för att bekräfta medgivandet.

  7. Kontrollera att kolumnen Status säger Beviljad för standardkatalogen. Med den här inställningen behöver back-end-appen inte längre visa en samtyckesskärm för den inloggade användaren och kan direkt begära en åtkomsttoken. Den inloggade användaren har åtkomst till omfångsinställningen User.Read eftersom det är standardomfånget som appregistreringen skapas med.

    Skärmbild av azure-portalens autentiseringsapp med administratörsmedgivande som beviljats i statuskolumnen.

2. Installera npm-paket

I den föregående handledningen behövde backend-applikationen inga npm-paket för autentisering eftersom den enda autentiseringen tillhandahölls genom att konfigurera en identitetsprovider i Azure-portalen. I den här självstudien måste den inloggade användarens åtkomsttoken för bakänd-API:t bytas ut mot en åtkomsttoken för Microsoft Graph. Det här utbytet har slutförts med två bibliotek eftersom det här utbytet inte längre använder App Service-autentisering, men Microsoft Entra-ID och MSAL.js direkt.

  1. Öppna Azure Cloud Shell och navigera till exempelkatalogens backend-app.

    cd js-e2e-web-app-easy-auth-app-to-app/backend
    
  2. Installera Azure MSAL npm-paketet:

    npm install @azure/msal-node
    
  3. Installera Microsoft Graph npm-paketet:

    npm install @microsoft/microsoft-graph-client
    

3. Lägg till kod för att byta ut aktuell token mot Microsoft Graph-token

Källkoden för att slutföra det här steget tillhandahålls åt dig. Använd följande steg för att inkludera det.

  1. Öppna ./src/server.js-filen.

  2. Ta bort kommenteringen av följande beroende överst i filen:

    import { getGraphProfile } from './with-graph/graph';
    
  3. I samma fil avkommentar du variabeln graphProfile :

    let graphProfile={};
    
  4. I samma fil avkommentar du följande getGraphProfile rader i get-profile vägen för att hämta profilen från Microsoft Graph:

    // where did the profile come from
    profileFromGraph=true;
    
    // get the profile from Microsoft Graph
    graphProfile = await getGraphProfile(accessToken);
    
    // log the profile for debugging
    console.log(`profile: ${JSON.stringify(graphProfile)}`);
    
  5. Spara ändringarna: Ctrl + s.

  6. Återdeploya backend-applikationen:

    az webapp up --resource-group myAuthResourceGroup --name <back-end-app-name> 
    
    

4. Kontrollera serverdelskoden för att byta serverdels-API-token mot Microsoft Graph-token

För att kunna ändra serverdels-API:ets målgruppstoken för en Microsoft Graph-token måste serverdelsappen hitta klientorganisations-ID:t och använda det som en del av MSAL.js konfigurationsobjektet. Eftersom serverdelsappen är konfigurerad med Microsoft som identitetsleverantör, finns klientorganisations-ID:t och flera andra obligatoriska värden redan i App Service-appinställningarna.

Följande kod har redan angetts för dig i exempelappen. Du måste förstå varför det finns där och hur det fungerar så att du kan tillämpa det här arbetet på andra appar som du skapar som behöver samma funktioner.

Kontrollera koden för att hämta hyresgäst-ID:t

  1. Öppna ./backend/src/with-graph/auth.js-filen.

  2. getTenantId() Granska funktionen.

    export function getTenantId() {
    
        const openIdIssuer = process.env.WEBSITE_AUTH_OPENID_ISSUER;
        const backendAppTenantId = openIdIssuer.replace(/https:\/\/sts\.windows\.net\/(.{1,36})\/v2\.0/gm, '$1');
    
        return backendAppTenantId;
    }
    
  3. Den här funktionen hämtar det aktuella klient-ID:t från WEBSITE_AUTH_OPENID_ISSUER miljövariabeln. ID:t parsas ut ur variabeln med ett reguljärt uttryck.

Granska koden för att hämta Graph-token med hjälp av MSAL.js

  1. Fortfarande i ./backend/src/with-graph/auth.js filen, granska getGraphToken() funktionen.

  2. Skapa MSAL.js konfigurationsobjektet och använd MSAL-konfigurationen för att skapa clientCredentialAuthority. Konfigurera begäran å någon annans vägnar. Använd sedan acquireTokenOnBehalfOf för att byta serverdels-API:ets åtkomsttoken mot en Graph-åtkomsttoken.

    // ./backend/src/auth.js
    // Exchange current bearerToken for Graph API token
    // Env vars were set by App Service
    export async function getGraphToken(backEndAccessToken) {
    
        const config = {
            // MSAL configuration
            auth: {
                // the backend's authentication CLIENT ID 
                clientId: process.env.WEBSITE_AUTH_CLIENT_ID,
                // the backend's authentication CLIENT SECRET 
                clientSecret: process.env.MICROSOFT_PROVIDER_AUTHENTICATION_SECRET,
                // OAuth 2.0 authorization endpoint (v2)
                // should be: https://login.microsoftonline.com/BACKEND-TENANT-ID
                authority: `https://login.microsoftonline.com/${getTenantId()}`
            },
            // used for debugging
            system: {
                loggerOptions: {
                    loggerCallback(loglevel, message, containsPii) {
                        console.log(message);
                    },
                    piiLoggingEnabled: true,
                    logLevel: MSAL.LogLevel.Verbose,
                }
            }
        };
    
        const clientCredentialAuthority = new MSAL.ConfidentialClientApplication(config);
    
        const oboRequest = {
            oboAssertion: backEndAccessToken,
            // this scope must already exist on the backend authentication app registration 
            // and visible in resources.azure.com backend app auth config
            scopes: ["https://graph.microsoft.com/.default"]
        }
    
        // This example has App service validate token in runtime
        // from headers that can't be set externally
    
        // If you aren't using App service's authentication, 
        // you must validate your access token yourself
        // before calling this code
        try {
            const { accessToken } = await clientCredentialAuthority.acquireTokenOnBehalfOf(oboRequest);
            return accessToken;
        } catch (error) {
            console.log(`getGraphToken:error.type = ${error.type}  ${error.message}`);
        }
    }
    

5. Granska serverdelskoden för att få åtkomst till Microsoft Graph med den nya token

För att få åtkomst till Microsoft Graph som en användare som är inloggad i klientdelsprogrammet inkluderar ändringarna:

  • Konfiguration av Active Directory-appregistreringen med en API-behörighet till den underordnade tjänsten, Microsoft Graph, med det nödvändiga omfånget User.Read.
  • Bevilja administratörsmedgivande för att kringgå skärmen med användarmedgivande för serverdelsappen.
  • Ändra programkoden för att konvertera åtkomsttoken som skickas från klientdelsappen till en åtkomsttoken med nödvändig behörighet för den underordnade tjänsten, Microsoft Graph.

Nu när koden har rätt token för Microsoft Graph använder du den för att skapa en klient till Microsoft Graph och hämtar sedan användarens profil.

  1. Öppna ./backend/src/graph.js

  2. getGraphProfile() I funktionen hämtar du först token, sedan den autentiserade klienten från token, och därefter hämtar du profilen.

    // 
    import graph from "@microsoft/microsoft-graph-client";
    import { getGraphToken } from "./auth.js";
    
    // Create client from token with Graph API scope
    export function getAuthenticatedClient(accessToken) {
        const client = graph.Client.init({
            authProvider: (done) => {
                done(null, accessToken);
            }
        });
    
        return client;
    }
    export async function getGraphProfile(accessToken) {
        // exchange current backend token for token with 
        // graph api scope
        const graphToken = await getGraphToken(accessToken);
    
        // use graph token to get Graph client
        const graphClient = getAuthenticatedClient(graphToken);
    
        // get profile of user
        const profile = await graphClient
            .api('/me')
            .get();
    
        return profile;
    }
    

6. Testa dina ändringar

  1. Använd klientdelswebbplatsen i en webbläsare. Du kan behöva uppdatera din token om den har upphört att gälla.

  2. Välj Get user's profile. Detta skickar din autentisering i ägartoken till serverdelen.

  3. Serverdelen svarar med den riktiga Microsoft Graph-profilen för ditt konto.

    Skärmbild av webbläsaren som visar framändaplattformen efter att den verkliga profilen har hämtats från backend-applikationen.

7. Städa upp

I de föregående stegen skapade du Azure-resurser i en resursgrupp.

  1. Ta bort resursgruppen genom att köra följande kommando i Cloud Shell. Det kan ta en minut att köra det här kommandot.

    az group delete --name myAuthResourceGroup
    
  2. Använd autentiseringsapparnas klient-ID, som du tidigare hittade och antecknade i avsnitten Enable authentication and authorization för serverdels- och klientdelsapparna.

  3. Ta bort appregistreringar för både klient- och serverdelsappar.

    # delete app - do this for both frontend and backend client ids
    az ad app delete <client-id>
    

Vanliga frågor

Jag fick ett fel 80049217, vad betyder det?

Det här felet CompactToken parsing failed with error code: 80049217innebär att serverdelsapptjänsten inte har behörighet att returnera Microsoft Graph-token. Det här felet beror på att appregistreringen saknar behörigheten User.Read .

Jag fick ett fel AADSTS65001, vad betyder det?

Det här felet innebär AADSTS65001: The user or administrator has not consented to use the application with ID \<backend-authentication-id>. Send an interactive authorization request for this user and resourceatt autentiseringsappen för serverdelen inte har konfigurerats för administratörsmedgivande. Eftersom felet visas i loggen för serverdelsappen kan klientdelsprogrammet inte berätta för användaren varför de inte såg sin profil i klientdelsappen.

Hur ansluter jag till en annan nedströms Azure-tjänst som användare?

Den här självstudien visar en API-app som autentiseras mot Microsoft Graph, men samma allmänna steg kan tillämpas för att få åtkomst till valfri Azure-tjänst för användarens räkning.

  1. Ingen ändring av frontend-applikationen. Endast ändringar i serverdelens autentiseringsappregistrering och källkod för serverdelsappen.
  2. Byt ut användarens token för serverdels-API:et mot en token till den nedströms tjänst du vill få åtkomst till.
  3. Använd token i underordnad tjänsts SDK för att skapa klienten.
  4. Använd underordnad klient för att få åtkomst till tjänstfunktioner.

Nästa steg