Uso del inicio de sesión único (SSO) en complementos de Office con Microsoft Graph

Completado

Los usuarios inician sesión en Office (en plataformas en línea, móviles o de escritorio) con su cuenta Microsoft personal, Microsoft 365 Educación o profesional.

La mejor manera de que un complemento de Office obtenga acceso autorizado a Microsoft Graph es usar las credenciales del inicio de sesión de Office del usuario. Esto les permite acceder a sus datos de Microsoft Graph sin necesidad de iniciar sesión una segunda vez.

En esta unidad, aprenderá a implementar SSO en un complemento de Office para enviar solicitudes y recuperar información de Microsoft Graph.

Complementos de Office, SSO y Microsoft Graph

Para empezar, echemos un vistazo a cómo funciona el flujo de autenticación en tiempo de ejecución cuando un complemento de Office implementa SSO con el objetivo final de acceder a Microsoft Graph.

Diagrama de vista general de flujo de autenticación SSO con complementos de Office y Microsoft Graph.

  1. En el complemento, JavaScript llama al método getAccessToken() de la API de Office.js. Esto indica a la aplicación cliente de Office que obtenga un token de acceso al complemento.

    Nota:

    A este token se le llama token de acceso de arranque porque se reemplaza por un segundo token más adelante en el proceso.

  2. Si el usuario no ha iniciado sesión, la aplicación cliente de Office abre una ventana emergente para que lo haga.

  3. Si se trata de la primera vez que el usuario actual usa el complemento, se pide su consentimiento.

  4. La aplicación cliente de Office solicita el token de acceso de arranque del punto de conexión de Azure AD v2.0 para el usuario actual.

  5. Microsoft Entra ID devuelve el token de arranque a la aplicación cliente de Office.

  6. La aplicación cliente de Office envía el token de acceso de arranque al complemento como parte del objeto de resultado que devuelve la llamada a getAccessToken().

  7. En el complemento, JavaScript realiza una solicitud HTTP a una API web que se hospeda en el mismo dominio completo que el complemento e incluye el token de acceso de arranque como prueba de autorización.

  8. El código del lado de servidor valida el token de acceso de arranque recibido.

  9. El código del lado de servidor usa el flujo con derechos delegados (OBO) de OAuth2 para obtener un token de acceso para Microsoft Graph a cambio del token de acceso de arranque.

  10. Microsoft Entra ID devuelve el token de acceso a Microsoft Graph y un token de actualización, si el complemento solicita offline_access permiso, al complemento.

  11. El código del lado servidor almacena en caché el token de acceso a Microsoft Graph.

  12. El código del lado del servidor realiza solicitudes a Microsoft Graph e incluye el token de acceso a Microsoft Graph.

  13. Microsoft Graph devuelve datos al complemento, que puede pasarlos a la interfaz de usuario del complemento.

  14. Cuando el token de acceso a Microsoft Graph caduca, el código del lado servidor puede usar su token de actualización para obtener un nuevo token de acceso a Microsoft Graph.

Los pasos descritos anteriormente indican que Office puede solicitar al usuario que otorgue su consentimiento para los permisos del complemento para iniciar sesión. Sin embargo, merece la pena tener en cuenta que Office solo puede solicitar consentimiento para el ámbito de profile OpenID. Office no puede pedir al usuario que otorgue su consentimiento a ninguno de los permisos de Microsoft Graph.

Esto puede presentar un problema con el complemento porque no puede saber si este token de arranque inicial se puede usar en OBO de OAuth2 para obtener un token de acceso para llamar a Microsoft Graph.

Si el código necesita permisos para Microsoft Graph o más permisos que el usuario aún no ha dado su consentimiento, cuando Microsoft Graph reciba el token de arranque, se producirá un error con un código de error específico: AADSTS65001. Este código de error indica que aún no se han concedido los permisos de Microsoft Graph solicitados.

El complemento debe controlar correctamente este escenario con un sistema de autorización de reserva que pida al usuario que otorgue su consentimiento para los permisos necesarios de Microsoft Graph.

Evasión de varios recorridos de ida y vuelta: error inmediato

Una cosa que observará en estos pasos son los muchos viajes de ida y vuelta a Microsoft Entra ID. Esto es cierto sobre todo cuando se solicita un token de acceso para usarlo con Microsoft Graph. El complemento tendrá que iniciar varios recorridos de ida y vuelta para poder averiguar si el usuario necesita otorgar su consentimiento a más permisos para Microsoft Graph.

El método getAccessToken() en el SDK de Office.js acepta un objeto de opciones que puede usar para implementar un enfoque de error inmediato. Si pasa { forMSGraphAccess: true } a este método, Microsoft Entra ID realizará una comprobación adicional antes de devolver el token de arranque.

Si el usuario ha otorgado su consentimiento para los permisos de Microsoft Graph solicitados, el complemento recibirá el token de arranque que puede usar para intercambiar con Microsoft Graph mediante el flujo OBO de OAuth2 para obtener un token de acceso que se puede usar para llamar a Microsoft Graph.

Sin embargo, si el usuario no ha dado su consentimiento a los permisos solicitados de Microsoft Graph, Microsoft Entra ID responderá con un error 13012. Su código puede controlar este error volviendo al sistema de autorización alternativo. Este proceso alternativo abrirá un cuadro de diálogo y pedirá al usuario que otorgue su consentimiento para los permisos de Microsoft Graph necesarios.

De este modo, el complemento puede evitar varias solicitudes solo para averiguar que el usuario necesita dar su consentimiento para los permisos de Microsoft Graph.

El código del proyecto predeterminado de SSO del complemento de Office incluye el código reutilizable necesario para implementar este proceso de autorización de reserva. Todos se encuentran como archivos ./helpers/fallbackauth*.* , una colección de archivos HTML y JavaScript que implementan el cuadro de diálogo emergente.

Llamada a Microsoft Graph desde el código del lado cliente

Para enviar una solicitud a Microsoft Graph, primero llame al método getAccessToken() como se indica a continuación. En este ejemplo, se pasa la opción allowSignInPrompt: true que puede usar si es posible utilizar el complemento a su inicio y no hay ningún usuario con sesión iniciada.

const sso = require("office-addin-sso");

// ...

let bootstrapToken = await OfficeRuntime.auth.getAccessToken({ allowSignInPrompt: true });

Captura de pantalla de inicio de sesión en Word.

A continuación, intentará intercambiar este token de arranque por un token de acceso que se puede usar para llamar a Microsoft Graph. Es esta parte la que inicia el flujo OBO de OAuth2:

let exchangeResponse = await sso.getGraphToken(bootstrapToken);

Suponiendo que el usuario ha otorgado su consentimiento para los permisos de Microsoft Graph necesarios, puede solicitar la información de perfil del usuario desde Microsoft Graph al llamar al método makeGraphApiCall() que se incluye con el paquete de JavaScript office-addin-sso:

const response = await sso.makeGraphApiCall(exchangeResponse.access_token);

Si necesita más control sobre la solicitud a Microsoft Graph, incluida la llamada a un punto de conexión específico o proporcionar más control sobre los parámetros de dirección URL, puede usar el método getGraphData():

const endpoint = "/me/messages";
const urlParams = "?$select=receivedDateTime,subject,isRead&$orderby=receivedDateTime&$top=10";
const response = await sso.getGraphData(exchangeResponse.access_token, endpoint, urlParams);

Como se mencionó anteriormente, si el usuario no ha concedido el consentimiento a Microsoft Graph para los permisos necesarios o si necesita iniciar sesión, todos los fragmentos de código mencionados anteriormente se pueden encapsular en un try-catch bloque que controla los errores de autenticación y autorización devueltos por Microsoft Entra ID. En esos casos, se implementa el sistema de diálogos de autorización de reserva:

const fallbackAuthHelper = require("./fallbackAuthHelper");

// ...

try {
  // 1. get bootstrap token
  // 2. exchange bootstrap token for access token
  // 3. call Microsoft Graph
} catch (exception) {
  if (exception.code) {
    if (sso.handleClientSideErrors(exception)) {
      fallbackAuthHelper.dialogFallback();
    }
  } else {
    sso.showMessage("EXCEPTION: " + JSON.stringify(exception));
  }
}