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

Lär dig hur du skapar och konfigurerar en App Service-app för serverdelen så att den accepterar en klientdelsapps användarautentiseringsuppgifter och sedan utbyter autentiseringsuppgifterna för en nedströms Azure-tjänst. Med den här metoden kan en användare logga in på en App Service-app på klientsidan, 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 autentiseringsappen för backend för att tillhandahålla en token med avgränsning för den underordnade tjänsten på Azure.
  • 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 Access Microsoft Graph från en skyddad JavaScript-app som användare innan du påbörjar den här självstudien. Ta inte bort resurserna i slutet av tutorialen. Den här självstudien 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 du skickar användaruppgifterna som tillhandahålls av frontend-appen till backend-appen och sedan över 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:

I den föregående självstudien behandlades:

  1. Logga in användaren till en frontend-applikation som har konfigurerats för att använda Active Directory som identitetsleverantör.
  2. Klientdelsapptjänsten skickar användarens token till serverdelsapptjänsten.
  3. Backend-applikationen är skyddad för att möjliggöra att frontend kan göra en API-förfrågan. Användarens åtkomsttoken har en målgrupp för serverdels-API:et och för omfånget user_impersonation.
  4. Backend-appregistreringen har redan Microsoft Graph med omfånget User.Read. Det här omfånget läggs som standard till i alla appregistreringar.
  5. I slutet av den föregående självstudien returnerades en fejk profil till frontend-appen 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 byta ut token för back-end-appar för att få en ny token med omfattningen av en nedströms Azure-tjänst, till exempel Microsoft Graph.
  4. Ange kod för att få serverdelsappen att använda ny token för att komma åt underordnade tjänster 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 frontendappen från tidigare handledning.
  • Ändra omfångsbehörigheten för backend-autentiseringsappen eftersom User.Read den läggs till som standard i alla autentiseringsappar.

I den föregående handledningen, när användaren loggar in på frontend-appen, ber ett popup-fönster om användarens medgivande.

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å det här problemet genom att konfigurera serverdelsappens appregistrering i Microsoft Entra-ID för att ge administratörsmedgivande. En Microsoft Entra-administratör gör vanligtvis den här inställningen ändrad.

  1. Öppna Azure-portalen och sök efter din resurs för back-end App Service.

  2. Hitta Inställningar>Autentisering avsnittet.

  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 självstudien behövde serverdelsappen inga npm-paket för autentisering eftersom den enda autentiseringen tillhandahölls genom att konfigurera identitetsprovidern 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. I stället använder den Microsoft Entra-ID och MSAL.js direkt.

  1. Öppna Azure Cloud Shell och ändra till exempelkatalogens serverdelsapp:

    cd js-e2e-web-app-easy-auth-app-to-app/backend
    
  2. Installera Azure Microsoft Authentication Library (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. Ominstallera serverdelsappen:

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

4. Granska serverdelskoden för att byta api-token för serverdelen mot Microsoft Graph-token

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

Följande kod tillhandahålls åt 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. ./backend/src/with-graph/auth.js Granska funktionen i getGraphToken() filen.

  2. Skapa konfigurationsobjektet MSAL.js. Använd MSAL-konfigurationen för att skapa clientCredentialAuthority. Konfigurera begäran å någon annans vägnar. Använd acquireTokenOnBehalfOf sedan för att byta ut serverdelens API-å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 token, sedan den autentiserade klienten från token och hämtar sedan 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 frontend-webbplatsen 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 en webbläsare som visar front-end-applikationen efter att ha hämtat den riktiga profilen från back-end-applikationen.

7. Städa upp

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

  1. Om du vill ta bort resursgruppen kör du 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 klient-ID:t 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 front-end and back-end client ids
    az ad app delete --id <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 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 resourceinnebär att backend-autentiseringsappen 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?

Tutorialen demonstrerar en API-app som autentiserats för Microsoft Graph. Samma allmänna steg kan användas 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 autentiseringsappregistreringen för serverdelen och i källkoden för serverdelsappen.
  2. Byt ut användarens token för back-end API till en token till den nedströms tjänst som du vill komma åt.
  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.