Office UI Outlook addin using auth is unstable

Viewed 576

We're currently developing a Office UI addin using React. The addin should make a connection with a backend api and authenticate the user using bearer tokens. The backend api is protected by Azure AD.

We based our solution on the example that is offered by Microsoft: https://github.com/OfficeDev/PnP-OfficeAddins/tree/master/Samples/auth/Office-Add-in-Microsoft-Graph-React This uses msal.js for the authentication.

The login dialog is opened like so:

await Office.context.ui.displayDialogAsync(dialogLoginUrl, { height: 40, width: 30 }, result => {
      if (result.status === Office.AsyncResultStatus.Failed) {
        displayError(`${result.error.code} ${result.error.message}`);
      } else {
        loginDialog = result.value;
        loginDialog.addEventHandler(Office.EventType.DialogMessageReceived, processLoginMessage);
        loginDialog.addEventHandler(Office.EventType.DialogEventReceived, processLoginDialogEvent);
      }
    });

And the following code runs within the dialog:

import { UserAgentApplication } from "msal";
(() => {
  // The initialize function must be run each time a new page is loaded
  Office.initialize = () => {
    const config = {
      auth: {
        clientId: "",
        authority: "",
        redirectUri: "https://localhost:3000/login.html",
        navigateToLoginRequestUrl: false
      },
      cache: {
        cacheLocation: "localStorage",
        storeAuthStateInCookie: false
      }
    };

    const userAgentApp = new UserAgentApplication(config);

    const authCallback = (error, response) => {
      if (!error) {
        if (response.tokenType === "id_token") {
          localStorage.setItem("loggedIn", "yes");
        } else {
          // The tokenType is access_token, so send success message and token.
          Office.context.ui.messageParent(JSON.stringify({ status: "success", result: response.accessToken }));
        }
      } else {
        const errorData = `errorCode: ${error.errorCode}
                                   message: ${error.errorMessage}
                                   errorStack: ${error.stack}`;
        Office.context.ui.messageParent(JSON.stringify({ status: "failure", result: errorData }));
      }
    };

    userAgentApp.handleRedirectCallback(authCallback);
    const request = {
      scopes: ["api://..."]
    };
    if (localStorage.getItem("loggedIn") === "yes") {
      userAgentApp.acquireTokenRedirect(request);
    } else {
      // This will login the user and then the (response.tokenType === "id_token")
      // path in authCallback below will run, which sets localStorage.loggedIn to "yes"
      // and then the dialog is redirected back to this script, so the
      // acquireTokenRedirect above runs.
      userAgentApp.loginRedirect(request);
    }
  };
})();

Unfortunately this doesn't seem lead to a stable addin. The authentication dialog sometimes works as expected, but sometimes it doesn't. In Outlook on macOS it seems to work fine, but in Outlook on Windows the handling of the callback is not always working correctly. Also in the web version of Outlook it doesn't work as expected.

The question is whether someone has a working solution using React and msal.js in a Outlook addin.

0 Answers
Related