Condividi tramite


Esercitazione: Eseguire il flusso dell'autenticazione dal servizio app tramite l'API back-end a Microsoft Graph

Informazioni su come creare e configurare un servizio app back-end per accettare le credenziali utente di un'app front-end, quindi scambiare tali credenziali per un servizio di Azure downstream. In questo modo un utente può accedere a un servizio app front-end, passare le credenziali a un servizio app back-end e quindi accedere a un servizio di Azure con la stessa identità.

In questa esercitazione si apprenderà come:

  • Configurare l'app di autenticazione back-end per fornire un token con ambito per il servizio di Azure downstream
  • Usare il codice JavaScript per scambiare il token di accesso dell'utente connesso per un nuovo token per il servizio downstream.
  • Usare il codice JavaScript per accedere al servizio downstream.

Prerequisiti

Completare l'esercitazione precedente, Accedere a Microsoft Graph da un'app JavaScript protetta come utente, prima di iniziare questa esercitazione, ma non rimuovere le risorse alla fine dell'esercitazione. Questa esercitazione presuppone che siano disponibili i due servizi app e le app di autenticazione corrispondenti.

Nella precedente esercitazione, è stato utilizzato Azure Cloud Shell come ambiente shell per l'uso dell'interfaccia della riga di comando di Azure. Questa esercitazione continua l'utilizzo.

Architettura

L'esercitazione illustra come passare le credenziali utente fornite dall'app front-end all'app back-end e quindi a un servizio di Azure. In questa esercitazione il servizio downstream è Microsoft Graph. Le credenziali dell'utente vengono usate per ottenere il proprio profilo da Microsoft Graph.

Immagine dell'architettura del Servizio App che si collega a Microsoft Graph per conto di un utente autenticato.

Flusso di autenticazione per consentire a un utente di ottenere informazioni su Microsoft Graph in questa architettura:

Esercitazione precedente ha trattato:

  1. Effettuare l'accesso dell'utente a un servizio frontend configurato per utilizzare Active Directory come provider di identità.
  2. Il servizio app front-end passa il token dell'utente al servizio app back-end.
  3. L'app back-end è protetta per consentire al front-end di effettuare una richiesta API. Il token di accesso dell'utente ha un gruppo di destinatari per l'API back-end e l'ambito di user_impersonation.
  4. La registrazione dell'app back-end ha già Microsoft Graph con l'ambito User.Read. Questa opzione viene aggiunta per impostazione predefinita a tutte le registrazioni dell'app.
  5. Alla fine dell'esercitazione precedente, un profilo falso è stato restituito all'app front-end perché Graph non è stato connesso.

Questa esercitazione estende l'architettura del sistema:

  1. Concedere all'amministratore il consenso per ignorare la schermata di consenso dell'utente per l'app back-end.
  2. Modificare il codice dell'applicazione per convertire il token di accesso inviato dall'app front-end a un token di accesso con l'autorizzazione necessaria per Microsoft Graph.
  3. Fornire il codice per consentire all'applicazione back-end di scambiare un token per un nuovo token con l'ambito del servizio Azure a valle, come ad esempio Microsoft Graph.
  4. Specificare il codice per fare in modo che l'app back-end usi un nuovo token per accedere al servizio downstream come utente autenticato corrente.
  5. Ridistribuire l'app back-end con az webapp up.
  6. Alla fine di questa esercitazione viene restituito un profilo reale all'app front-end perché Graph è connesso.

Questa esercitazione non:

  • Modifica l'app frontend rispetto all'esercitazione precedente.
  • Modificare l'autorizzazione di ambito dell'app di autenticazione back-end perché User.Read viene aggiunta per impostazione predefinita a tutte le app di autenticazione.

Nell'esercitazione precedente, quando l'utente ha eseguito l'accesso all'app front-end, viene visualizzato un popup che richiede il consenso dell'utente.

In questa esercitazione, per leggere il profilo utente da Microsoft Graph, l'app back-end deve scambiare il token di accesso dell'utente connesso per un nuovo token di accesso con le autorizzazioni necessarie per Microsoft Graph. Poiché l'utente non è connesso direttamente all'app back-end, non può accedere alla schermata di consenso in modo interattivo. È necessario aggirare questo problema configurando la registrazione dell'app back-end in Microsoft Entra ID per garantire il consenso dell'amministratore. Si tratta di una modifica dell'impostazione eseguita in genere da un amministratore di Active Directory.

  1. Apri il portale di Azure e cerca il servizio App Service back-end relativo alla tua ricerca.

  2. Trovare la sezione Impostazioni -> Autenticazione .

  3. Selezionare il provider di identità per passare all'app di autenticazione.

  4. Nell'app di autenticazione selezionare Gestisci -> Autorizzazioni API.

  5. Selezionare Concedi consenso amministratore per directory predefinita.

    Screenshot dell'app di autenticazione del portale di Azure con il pulsante di consenso amministratore evidenziato.

  6. Nella finestra popup selezionare per confermare il consenso.

  7. Verificare che la colonna Stato sia concessa per la directory predefinita. Con questa impostazione, l'app back-end non è più necessaria per visualizzare una schermata di consenso all'utente connesso e può richiedere direttamente un token di accesso. L'utente connesso ha accesso all'impostazione dell'ambito User.Read perché è l'ambito predefinito con cui viene creata la registrazione dell'app.

    Screenshot dell'app di autenticazione del portale di Azure con il consenso dell'amministratore concesso nella colonna dello stato.

2. Installare pacchetti npm

Nell'esercitazione precedente l'app back-end non ha bisogno di pacchetti npm per l'autenticazione perché l'unica autenticazione è stata fornita configurando il provider di identità nel portale di Azure. In questa esercitazione, il token di accesso dell'utente connesso per l'API back-end deve essere scambiato per un token di accesso con Microsoft Graph nel relativo ambito. Questo scambio viene completato con due librerie perché questo scambio non utilizza più l'autenticazione del servizio App Service, ma direttamente Microsoft Entra ID e MSAL.js.

  1. Aprire Azure Cloud Shell e passare all'app back-end della directory di esempio:

    cd js-e2e-web-app-easy-auth-app-to-app/backend
    
  2. Installare il pacchetto npm msal di Azure:

    npm install @azure/msal-node
    
  3. Installare il pacchetto npm di Microsoft Graph:

    npm install @microsoft/microsoft-graph-client
    

3. Aggiungere codice per scambiare il token corrente per il token Microsoft Graph

Il codice sorgente per completare questo passaggio viene fornito. Per includerlo, seguire questa procedura.

  1. Aprire il file ./src/server.js.

  2. Rimuovere il commento dalla dipendenza seguente all'inizio del file:

    import { getGraphProfile } from './with-graph/graph';
    
  3. Nello stesso file, decommenta la variabile graphProfile.

    let graphProfile={};
    
  4. Nello stesso file rimuovere il commento dalle righe seguenti getGraphProfile nella get-profile route per ottenere il profilo da 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. Salvare le modifiche: CTRL + S.

  6. Ridistribuire l'app backend:

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

4. Esaminare il codice back-end per scambiare il token API back-end per il token Microsoft Graph

Per modificare il token del gruppo di destinatari dell'API back-end per un token di Microsoft Graph, l'app back-end deve trovare l'ID tenant e usarlo come parte dell'oggetto di configurazione MSAL.js. Poiché l'app back-end è configurata con Microsoft come provider di identità, l'ID del tenant e diversi altri valori obbligatori sono già presenti nelle impostazioni dell'app del servizio dell'app.

Il codice seguente è già disponibile nell'app di esempio. È necessario capire perché è presente e come funziona in modo da poter applicare questo lavoro ad altre app che si creano che necessitano di questa stessa funzionalità.

Esaminare il codice per ottenere l'ID tenant

  1. Aprire il file ./backend/src/with-graph/auth.js.

  2. Esaminare la funzione getTenantId().

    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. Questa funzione ottiene l'ID tenant corrente dalla WEBSITE_AUTH_OPENID_ISSUER variabile di ambiente. L'ID viene estratto dalla variabile con un'espressione regolare.

Esaminare il codice per ottenere il token Graph usando MSAL.js

  1. Sempre nel ./backend/src/with-graph/auth.js file, esaminare la funzione di getGraphToken().

  2. Compilare l'oggetto di configurazione MSAL.js, usare la configurazione MSAL per creare clientCredentialAuthority. Configurare la richiesta on-behalf-off. Usare quindi acquireTokenOnBehalfOf per scambiare il token di accesso dell'API back-end per un token di accesso graph.

    // ./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. Esaminare il codice back-end per accedere a Microsoft Graph con il nuovo token

Per accedere a Microsoft Graph come utente che ha eseguito l'accesso all'applicazione front-end, le modifiche includono:

  • Configurazione della registrazione dell'app Active Directory con un'autorizzazione API per il servizio downstream, Microsoft Graph, con l'ambito necessario di User.Read.
  • Concedere all'amministratore il consenso per ignorare la schermata di consenso dell'utente per l'app back-end.
  • Modificare il codice dell'applicazione per convertire il token di accesso inviato dall'app front-end a un token di accesso con l'autorizzazione necessaria per il servizio downstream, Microsoft Graph.

Ora che il codice ha il token corretto per Microsoft Graph, usarlo per creare un client a Microsoft Graph e quindi ottenere il profilo dell'utente.

  1. Aprire il ./backend/src/graph.js

  2. Nella funzione getGraphProfile(), ottenere il token, poi il client autenticato dal token, e infine ottenere il profilo.

    // 
    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. Testare le modifiche

  1. Usare il sito Web front-end in un browser. Potrebbe essere necessario aggiornare il token se è scaduto.

  2. Seleziona Get user's profile. Questa operazione passa l'autenticazione nel token di connessione al back-end.

  3. Il back-end risponde con il profilo reale di Microsoft Graph per il tuo account.

    Screenshot del browser web che mostra l'applicazione frontend dopo aver ottenuto correttamente il profilo reale dall'app backend.

7. Pulire

Nei passaggi precedenti sono state create risorse di Azure in un gruppo di risorse.

  1. Eliminare il gruppo di risorse eseguendo il comando seguente in Cloud Shell. L'esecuzione del comando può richiedere un minuto.

    az group delete --name myAuthResourceGroup
    
  2. Usare l'ID client delle app di autenticazione, trovato in precedenza e annotato nelle Enable authentication and authorization sezioni per le app back-end e front-end.

  3. Eliminare le registrazioni delle app sia per le app front-end che per le app back-end.

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

Domande frequenti

Si è verificato un errore 80049217, cosa significa?

Questo errore indica CompactToken parsing failed with error code: 80049217che il servizio app back-end non è autorizzato a restituire il token di Microsoft Graph. Questo errore è causato perché la registrazione dell'app non ha l'autorizzazione User.Read .

Si è verificato un errore AADSTS65001, cosa significa?

Questo errore indica 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 resourceche l'app di autenticazione back-end non è stata configurata per il consenso amministratore. Poiché l'errore viene visualizzato nel log per l'app back-end, l'applicazione front-end non può indicare all'utente perché non ha visualizzato il profilo nell'app front-end.

Come ci si connette a un altro servizio downstream di Azure come utente?

Questa esercitazione illustra un'app per le API autenticata in Microsoft Graph, ma è possibile applicare gli stessi passaggi generali per accedere a qualsiasi servizio di Azure per conto dell'utente.

  1. Nessuna modifica all'applicazione front-end. Solo le modifiche apportate alla registrazione dell'app di autenticazione back-end e al codice sorgente dell'app back-end.
  2. Scambia il token dell'utente associato all'API back-end con un token per il servizio downstream che si desidera accedere.
  3. Usare il token nell'SDK del servizio downstream per creare il client.
  4. Usare il client downstream per accedere alle funzionalità del servizio.

Passaggi successivi