Tutorial: Flujo de la autenticación desde App Service a través de la API de back-end a Microsoft Graph

Aprenda a crear y configurar una aplicación de App Service de back-end para aceptar las credenciales de usuario de una aplicación front-end y, a continuación, intercambiar esa credencial para un servicio de Azure de nivel inferior. Este enfoque permite que un usuario inicie sesión en una aplicación de App Service front-end, pase sus credenciales a un servicio de App Service back-end y, a continuación, acceda a un servicio de Azure con la misma identidad.

En este tutorial, aprenderá a:

  • Configure la aplicación de autenticación de back-end para proporcionar un token específico para el servicio de Azure descendente.
  • Use código JavaScript para intercambiar el token de acceso del usuario que ha iniciado sesión para un nuevo token para el servicio de bajada.
  • Utiliza código JavaScript para acceder al servicio posterior.

Prerrequisitos

Complete el tutorial anterior , Acceso a Microsoft Graph desde una aplicación javaScript protegida como usuario, antes de iniciar este tutorial. No elimine los recursos al final del tutorial. En este tutorial se supone que tiene los dos servicios de aplicaciones y sus aplicaciones de autenticación correspondientes.

En el tutorial anterior se usó Azure Cloud Shell como shell para la CLI de Azure. Este tutorial continúa con ese uso.

Arquitectura

En el tutorial se muestra cómo pasar la credencial de usuario proporcionada por la aplicación front-end a la aplicación back-end y, después, a un servicio de Azure. En este tutorial, el servicio descendente es Microsoft Graph. La credencial del usuario se usa para obtener su perfil de Microsoft Graph.

Imagen arquitectónica de App Service conectándose a App Service conectándose a Microsoft Graph en nombre de un usuario que ha iniciado sesión.

Flujo de autenticación para que un usuario obtenga información de Microsoft Graph en esta arquitectura:

En el tutorial anterior se trató:

  1. Inicie sesión del usuario en una aplicación front-end configurada para usar Active Directory como proveedor de identidades.
  2. El servicio de aplicaciones front-end pasa el token del usuario al servicio de aplicaciones back-end.
  3. La aplicación back-end está protegida para permitir que el front-end realice una solicitud de API. El token de acceso del usuario tiene como destinatarios la API del servidor y el alcance de user_impersonation.
  4. El registro de la aplicación de back-end ya tiene Microsoft Graph con el ámbito User.Read. Este ámbito se agrega de forma predeterminada a todos los registros de aplicaciones.
  5. Al final del tutorial anterior, se devolvió un perfil falso a la aplicación front-end porque Graph no estaba conectado.

En este tutorial se amplía la arquitectura:

  1. Conceda consentimiento del administrador para omitir la pantalla de consentimiento del usuario para la aplicación back-end.
  2. Cambie el código de aplicación para convertir el token de acceso enviado desde la aplicación front-end a un token de acceso con el permiso necesario para Microsoft Graph.
  3. Proporcione código para que la aplicación de back-end intercambie un token por un nuevo token con el alcance del servicio descendente de Azure, como Microsoft Graph.
  4. Proporcione código para que la aplicación back-end use un nuevo token para acceder al servicio de bajada como el usuario autenticado actual.
  5. Vuelva a implementar la app de back-end con az webapp up.
  6. Al final de este tutorial, se devuelve un perfil real a la aplicación front-end porque Graph está conectado.

Este tutorial no:

  • Cambie la aplicación front-end del tutorial anterior.
  • Cambie el permiso de ámbito de la aplicación de autenticación de back-end porque User.Read se agrega de forma predeterminada a todas las aplicaciones de autenticación.

En el tutorial anterior, cuando el usuario inicia sesión en la aplicación front-end, una ventana emergente solicita el consentimiento del usuario.

En este tutorial, para leer el perfil de usuario de Microsoft Graph, la aplicación back-end debe intercambiar el token de acceso del usuario que ha iniciado sesión para un nuevo token de acceso con los permisos necesarios para Microsoft Graph. Dado que el usuario no está conectado directamente a la aplicación back-end, no puede acceder a la pantalla de consentimiento de forma interactiva. Debe solucionar este problema configurando el registro de aplicaciones de la aplicación de back-end en el identificador de Entra de Microsoft para conceder el consentimiento del administrador. Normalmente, un administrador de Microsoft Entra realiza este cambio de configuración.

  1. Abra Azure Portal y busque el recurso para el servicio de aplicaciones back-end.

  2. Busque la sección Configuración>Autenticación.

  3. Seleccione el proveedor de identidades para ir a la aplicación de autenticación.

  4. En la aplicación de autenticación, seleccione Administrar>permisos de API.

  5. Seleccione Conceder consentimiento del administrador para el directorio predeterminado.

    Captura de pantalla de la aplicación de autenticación de Azure Portal con el botón de consentimiento del administrador resaltado.

  6. En la ventana emergente, seleccione para confirmar el consentimiento.

  7. Compruebe que la columna Estado indica Concedido para el directorio predeterminado. Con esta configuración, la aplicación back-end ya no es necesaria para mostrar una pantalla de consentimiento al usuario que ha iniciado sesión y puede solicitar directamente un token de acceso. El usuario que ha iniciado sesión tiene acceso a la configuración del User.Read alcance porque es el alcance predeterminado con el que se crea el registro de la aplicación.

    Captura de pantalla de la aplicación de autenticación de Azure Portal con el consentimiento del administrador concedido en la columna de estado.

2. Instalación de paquetes de npm

En el tutorial anterior, la aplicación de back-end no necesitaba ningún paquete de npm para la autenticación porque la única autenticación se proporcionó mediante la configuración del proveedor de identidades en Azure Portal. En este tutorial, el token de acceso del usuario que ha iniciado sesión para la API de back-end debe intercambiarse para un token de acceso con Microsoft Graph en su ámbito. Este intercambio se completa con dos bibliotecas porque este intercambio ya no usa la autenticación de App Service. En su lugar, usa el identificador de Entra de Microsoft y MSAL.js directamente.

  1. Abra Azure Cloud Shell y cambie a la aplicación back-end del directorio de ejemplo:

    cd js-e2e-web-app-easy-auth-app-to-app/backend
    
  2. Instale el paquete npm de la biblioteca de autenticación de Microsoft (MSAL) de Azure:

    npm install @azure/msal-node
    
  3. Instale el paquete npm de Microsoft Graph:

    npm install @microsoft/microsoft-graph-client
    

3. Agregar código para intercambiar el token actual para el token de Microsoft Graph

El código fuente para completar este paso se proporciona automáticamente. Siga estos pasos para incluirlo.

  1. Abra el archivo ./src/server.js.

  2. Quite la marca de comentario de la siguiente dependencia en la parte superior del archivo:

    import { getGraphProfile } from './with-graph/graph';
    
  3. En el mismo archivo, descomente la variable graphProfile.

    let graphProfile={};
    
  4. En el mismo archivo, quite la marca de comentario de las siguientes getGraphProfile líneas en la get-profile ruta para obtener el perfil de 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. Guarde los cambios: Ctrl + s.

  6. Vuelva a implementar la aplicación back-end:

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

4. Inspeccione el código back-end para intercambiar el token de API de back-end por el token de Microsoft Graph

Para cambiar el token de audiencia de la API del back-end por un token de Microsoft Graph, la aplicación de back-end debe encontrar el ID de inquilino y usarlo como parte del objeto de configuración de MSAL.js. Dado que la aplicación back-end está configurada con Microsoft como proveedor de identidades, el identificador de inquilino y otros valores necesarios ya están en la configuración de la aplicación de App Service.

El código siguiente se proporciona automáticamente en la aplicación de ejemplo. Debe comprender por qué está ahí y cómo funciona para que pueda aplicar este trabajo a otras aplicaciones que cree que necesitan esta misma funcionalidad.

Inspección del código para obtener el id. de inquilino

  1. Abra el archivo ./backend/src/with-graph/auth.js.

  2. Revise la getTenantId() función .

    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. Esta función obtiene el identificador de inquilino actual de la WEBSITE_AUTH_OPENID_ISSUER variable de entorno. El identificador se extrae de la variable con una expresión regular.

Inspección del código para obtener el token de Graph mediante MSAL.js

  1. En el archivo ./backend/src/with-graph/auth.js, revisar la función getGraphToken().

  2. Compile el objeto de configuración MSAL.js. Utilice la configuración de MSAL para crear el clientCredentialAuthority. Configure la solicitud en nombre de otro. A continuación, use acquireTokenOnBehalfOf para intercambiar el token de acceso de la API de back-end por un token de acceso de 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. Inspeccione el código de back-end para acceder a Microsoft Graph con el nuevo token

Para acceder a Microsoft Graph como usuario que inició sesión en la aplicación front-end, los cambios incluyen:

  • Configuración del registro de aplicación de Active Directory con un permiso de API para el servicio de bajada, Microsoft Graph, con el ámbito necesario de User.Read.
  • Conceda consentimiento del administrador para omitir la pantalla de consentimiento del usuario para la aplicación back-end.
  • Cambie el código de la aplicación para convertir el token de acceso enviado desde la aplicación front-end en un token de acceso con el permiso necesario para el servicio descendente, Microsoft Graph.

Ahora que el código tiene el token correcto para Microsoft Graph, úselo para crear un cliente en Microsoft Graph y, a continuación, obtenga el perfil del usuario.

  1. Abra el ./backend/src/graph.js

  2. En la función getGraphProfile(), obtenga el token, después el cliente autenticado del token, y luego obtenga el perfil.

    // 
    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. Probar los cambios

  1. Utilice el sitio web front-end en un navegador web. Es posible que tenga que actualizar el token si ha expirado.

  2. Seleccione Get user's profile. Esto pasa tu autenticación en el token portador al backend.

  3. El back-end responde con el perfil real de Microsoft Graph para su cuenta.

    Captura de pantalla del explorador web que muestra la aplicación front-end después de obtener correctamente el perfil real de la aplicación back-end.

7. Limpiar

En los pasos anteriores, usted creó recursos de Azure en un grupo de recursos.

  1. Para eliminar el grupo de recursos, ejecute el siguiente comando en Cloud Shell. Este comando puede tardar un par de minutos en ejecutarse.

    az group delete --name myAuthResourceGroup
    
  2. Utiliza los identificadores de cliente que encontraste anteriormente y anotaste en las Enable authentication and authorization secciones para las aplicaciones de back-end y de front-end.

  3. Elimine los registros de aplicaciones para las aplicaciones front-end y back-end.

    # delete app - do this for both front-end and back-end client ids
    az ad app delete --id <client-id>
    

Preguntas más frecuentes

Tengo un error 80049217, ¿qué significa?

Este error, CompactToken parsing failed with error code: 80049217, significa que el App Service de back-end no está autorizado para devolver el token de Microsoft Graph. Este error se debe a que falta el permiso User.Read en el registro de la aplicación.

Tengo un error AADSTS65001, ¿qué significa?

Este error, 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 resource, significa que la aplicación de autenticación de back-end no se ha configurado para el consentimiento del administrador. Dado que el error aparece en el registro de la aplicación back-end, la aplicación front-end no puede indicar al usuario por qué no vio su perfil en la aplicación front-end.

¿Cómo puedo conectarse a un servicio de Azure de nivel inferior diferente como usuario?

En este tutorial se muestra una aplicación de API autenticada en Microsoft Graph. Se pueden aplicar los mismos pasos generales para acceder a cualquier servicio de Azure en nombre del usuario.

  1. No hay ningún cambio en la aplicación front-end. Solo se cambia el registro de aplicaciones de autenticación del back end y el código fuente de la aplicación del back end.
  2. Intercambie el token del usuario con ámbito de back-end API por un token para el servicio descendente que desea acceder.
  3. Utiliza el token en el SDK del servicio dependiente para crear el cliente.
  4. Use el cliente de bajada para acceder a la funcionalidad del servicio.