En este ejercicio, habilitará el inicio de sesión único (SSO) del complemento de Office en el complemento y ampliará la API web para que admita el flujo en nombre de.In this exercise you will enable Office Add-in single sign-on (SSO) in the add-in, and extend the web API to support on-behalf-of flow. Esto es necesario para obtener el token de acceso OAuth necesario para llamar a Microsoft Graph.This is required to obtain the necessary OAuth access token to call the Microsoft Graph.

Información generalOverview

El SSO del complemento de Office proporciona un token de acceso, pero ese token solo permite al complemento llamar a su propia API web.Office Add-in SSO provides an access token, but that token is only enables the add-in to call it's own web API. No habilita el acceso directo a Microsoft Graph.It does not enable direct access to the Microsoft Graph. El proceso funciona de la siguiente manera.The process works as follows.

  1. El complemento obtiene un token llamando a getAccessToken.The add-in gets a token by calling getAccessToken. La audiencia de este token (la notificación) es el identificador de aplicación del registro de la aplicación aud del complemento.This token's audience (the aud claim) is the application ID of the add-in's app registration.
  2. El complemento envía este token en el Authorization encabezado cuando realiza una llamada a la API web.The add-in sends this token in the Authorization header when it makes a call to the web API.
  3. La API web valida el token y, a continuación, usa el flujo en nombre de para intercambiar este token por un token de Microsoft Graph.The web API validates the token, then uses the on-behalf-of flow to exchange this token for a Microsoft Graph token. La audiencia de este nuevo token es https://graph.microsoft.com .This new token's audience is https://graph.microsoft.com.
  4. La API web usa el nuevo token para realizar llamadas a Microsoft Graph y devuelve los resultados al complemento.The web API uses the new token to make calls to the Microsoft Graph, and returns the results back to the add-in.

Configurar la soluciónConfigure the solution

  1. Abra ./.env y actualice el id. de aplicación y el secreto de cliente AZURE_APP_ID del registro de la AZURE_CLIENT_SECRET aplicación.Open ./.env and update the AZURE_APP_ID and AZURE_CLIENT_SECRET with the application ID and client secret from your app registration.

    Importante

    Si usas el control de código fuente como Git, ahora sería un buen momento para excluir el archivo .env del control de código fuente para evitar la pérdida involuntaria del identificador de la aplicación y el secreto de cliente.If you're using source control such as git, now would be a good time to exclude the .env file from source control to avoid inadvertently leaking your app ID and client secret.

  2. Abra ./manifest/manifest.xml y reemplace todas las instancias con el YOUR_APP_ID_HERE identificador de aplicación del registro de la aplicación.Open ./manifest/manifest.xml and replace all instances of YOUR_APP_ID_HERE with the application ID from your app registration.

  3. Cree un nuevo archivo en el directorio ./src/addin denominado config.js y agregue el siguiente código, reemplazando con el identificador de aplicación del registro YOUR_APP_ID_HERE de la aplicación.Create a new file in the ./src/addin directory named config.js and add the following code, replacing YOUR_APP_ID_HERE with the application ID from your app registration.

Implementar el inicio de sesiónImplement sign-in

  1. Abra ./src/api/auth.ts y agregue las siguientes import instrucciones en la parte superior del archivo.Open ./src/api/auth.ts and add the following import statements at the top of the file.

    import jwt, { SigningKeyCallback, JwtHeader } from 'jsonwebtoken';
    import jwksClient from 'jwks-rsa';
    import * as msal from '@azure/msal-node';
    
  2. Agregue el siguiente código después de import las instrucciones.Add the following code after the import statements.

    Este código inicializa un cliente confidencial de MSALy exporta una función para obtener un token de Graph del token enviado por el complemento.This code initializes an MSAL confidential client, and exports a function to get a Graph token from the token sent by the add-in.

  3. Agregue el siguiente código antes de la export default authRouter; línea.Add the following code before the export default authRouter; line.

    Este código implementa una API ( ) que comprueba si el token de complemento se puede intercambiar silenciosamente GET /auth/status por un token de Graph.This code implements an API (GET /auth/status) that checks if the add-in token can be silently exchanged for a Graph token. El complemento usará esta API para determinar si necesita presentar un inicio de sesión interactivo al usuario.The add-in will use this API to determine if it needs to present an interactive login to the user.

  4. Abra ./src/addin/taskpane.js y agregue el siguiente código al archivo.Open ./src/addin/taskpane.js and add the following code to the file.

    Este código agrega funciones para actualizar la interfaz de usuario y para usar la API de cuadros de diálogo de Office para iniciar un flujo de autenticación interactivo.This code adds functions to update the UI, and to use the Office Dialog API to initiate an interactive authentication flow.

  5. Agregue la siguiente función para implementar una interfaz de usuario principal temporal.Add the following function to implement a temporary main UI.

    function showMainUi() {
      $('.container').empty();
      $('<p/>', {
        class: 'ms-fontSize-24 ms-fontWeight-bold',
        text: 'Authenticated!'
      }).appendTo('.container');
    }
    
  6. Reemplace la llamada Office.onReady existente por lo siguiente.Replace the existing Office.onReady call with the following.

    Ten en cuenta lo que hace este código.Consider what this code does.

    • Cuando el panel de tareas se carga por primera vez, llama para obtener un token con ámbito para la getAccessToken API web del complemento.When the task pane first loads, it calls getAccessToken to get a token scoped for the add-in's web API.
    • Usa ese token para llamar a la API para comprobar si el usuario ha dado su consentimiento todavía a /auth/status los ámbitos de Microsoft Graph.It uses that token to call the /auth/status API to check if the user has given consent to the Microsoft Graph scopes yet.
      • Si el usuario no ha dado su consentimiento, usa una ventana emergente para obtener el consentimiento del usuario a través de un inicio de sesión interactivo.If the user has not consented, it uses a pop-up window to get the user's consent through an interactive login.
      • Si el usuario ha dado su consentimiento, carga la interfaz de usuario principal.If the user has consented, it loads the main UI.

Aunque el complemento usa SSO, el usuario todavía tiene que dar su consentimiento para que el complemento acceda a sus datos a través de Microsoft Graph.Even though the add-in is using SSO, the user still has to consent to the add-in accessing their data via Microsoft Graph. Obtener el consentimiento es un proceso único.Getting consent is a one-time process. Una vez que el usuario ha concedido el consentimiento, el token SSO se puede intercambiar por un token de Graph sin ninguna interacción del usuario.Once the user has granted consent, the SSO token can be exchanged for a Graph token without any user interaction. En esta sección, implementará la experiencia de consentimiento en el complemento con msal-browser.In this section you'll implement the consent experience in the add-in using msal-browser.

  1. Cree un nuevo archivo en el directorio ./src/addin denominado consent.js y agregue el siguiente código.Create a new file in the ./src/addin directory named consent.js and add the following code.

    Este código inicia sesión para el usuario y solicita el conjunto de permisos de Microsoft Graph configurados en el registro de la aplicación.This code does login for the user, requesting the set of Microsoft Graph permissions that are configured on the app registration.

  2. Cree un nuevo archivo en el directorio ./src/addin denominado consent.html y agregue el siguiente código.Create a new file in the ./src/addin directory named consent.html and add the following code.

    Este código implementa una página HTML básica para cargar el consent.js archivo.This code implements a basic HTML page to load the consent.js file. Esta página se cargará en un cuadro de diálogo emergente.This page will be loaded in a pop-up dialog.

  3. Guarde todos los cambios y reinicie el servidor.Save all of your changes and restart the server.

  4. Vuelva a cargar elmanifest.xml archivo con los mismos pasos de carga lateral del complemento en Excel.Re-upload your manifest.xml file using the same steps in Side-load the add-in in Excel.

  5. Seleccione el botón Importar calendario en la pestaña Inicio para abrir el panel de tareas.Select the Import Calendar button on the Home tab to open the task pane.

  6. Seleccione el botón Conceder permiso en el panel de tareas para iniciar el cuadro de diálogo de consentimiento en una ventana emergente.Select the Give permission button in the task pane to launch the consent dialog in a pop-up window. Inicie sesión y conceda su consentimiento.Sign in and grant consent.

  7. El panel de tareas se actualiza con un "Autenticado".The task pane updates with an "Authenticated!" Mensaje.message. Puede comprobar los tokens de la siguiente manera.You can check the tokens as follows.

    • En las herramientas para desarrolladores del brower, el token de API se muestra en la consola.In your brower's developer tools, the API token is shown in the Console.
    • En la CLI donde ejecuta el servidor Node.js, se imprime el token de Graph.In your CLI where you are running the Node.js server, the Graph token is printed.

    Puede comparar estos tokens en https://jwt.ms .You can compare these token at https://jwt.ms. Observe que la audiencia del token de API ( ) se establece en el identificador de aplicación del registro de la aplicación y el ámbito aud ( scp ) es access_as_user .Notice that the API token's audience (aud) is set to the application ID of your app registration, and the scope (scp) is access_as_user.