AzureAD / microsoft-authentication-library-for-js

Microsoft Authentication Library (MSAL) for JS
http://aka.ms/aadv2
MIT License
3.66k stars 2.65k forks source link

getAccountByHomeId returns null after a sucessfull login in Outlook addin. #6489

Closed EirikAan closed 1 year ago

EirikAan commented 1 year ago

Core Library

MSAL.js (@azure/msal-browser)

Core Library Version

2.28.1

Wrapper Library

Not Applicable

Wrapper Library Version

None

Public or Confidential Client?

Public

Description

recently the authentication flow for my outlook addin started acting weird. This has worked perfectly fine for months up until last week when suddenly i stopped working for me.

Currently the login process goes smooth and i sucessfully log in using msal and a dialog window popup in my addin.

However when i try to fetch my account from the MSAL storage it just returns null. trying to use getAllAccounts simply returns an empty array.

the weird part is that the error occurs in both local development and in production, even tough no code has been pushed since the last time it worked. The even weirder part is that the error only occurs on my pc. And i havent done anything to prompt this. I tested the solution on wednesday last week, and it worked fine. And when i booted the same stuff up on thursday it didnt work.

Any ideas what can cause this? I tried running this sample on my pc https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/samples/msal-react-samples/react-router-sample and that worked fine. I tried running the diffrent methods to fetch accounts and they all returned something. Is this an issue with v2? Would upgrading to v3 help?

MSAL Configuration

export const msalConfig: Configuration = {
  auth: { 
    clientId: CLIENT_ID,
    authority: `https://login.microsoftonline.com/${TENANT_ID}`,
    redirectUri: `${OUTLOOK_ADDIN_HOST}/fallbackauthdialog.html`,
    navigateToLoginRequestUrl: false,
  },
  cache: {
    cacheLocation: BrowserCacheLocation.LocalStorage,
    storeAuthStateInCookie: true,
  },
};

Relevant Code Snippets

import {
  AuthenticationResult,
  // EventMessage,
  // EventType,
  PublicClientApplication,
} from "@azure/msal-browser";
import { loginRequest, msalConfig } from "./authConfig";

const publicClientApp: PublicClientApplication = new PublicClientApplication(msalConfig);

Office.onReady(() => {
  if (Office.context.ui.messageParent) {
    publicClientApp
      .handleRedirectPromise()
      .then(handleResponse)
      .catch((error) => {
        console.log(error);
        Office.context.ui.messageParent(JSON.stringify({ status: "failure", result: error }));
      });

    // The very first time the add-in runs on a developer's computer, msal.js hasn't yet
    // stored login data in localStorage. So a direct call of acquireTokenRedirect
    // causes the error "User login is required". Once the user is logged in successfully
    // the first time, msal data in localStorage will prevent this error from ever hap-
    // pening again; but the error must be blocked here, so that the user can login
    // successfully the first time. To do that, call loginRedirect first instead of
    // acquireTokenRedirect.
    if (localStorage.getItem("loggedIn") === "yes") {
      console.log("user is logged in");
      publicClientApp.acquireTokenRedirect(loginRequest);
    } 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.
      console.log("Redirecting to login");
      publicClientApp.loginRedirect(loginRequest);
    }
  }
});
function handleResponse(response: AuthenticationResult | null) {
  console.log("Handeling authentication result");
  if(response)  {
    console.log(response);
    if (response.tokenType === "id_token") {
      console.log("LoggedIn");
      localStorage.setItem("loggedIn", "yes");
    } else {
      console.log("token type is:" + response.tokenType);
      Office.context.ui.messageParent(
        JSON.stringify({ status: "success", result: response.accessToken, accountId: response.account?.homeAccountId })
      );
    }
  } else {
    console.log("No response");
  }
}

export async function getAccessToken(onSuccess?: () => void): Promise<string> {
  try {
    // Attempt to get token through SSO.
    console.log("Attempt to get token through SSO");
    const accessToken = await publicClientApp.acquireTokenSilent(loginRequest);
    if (onSuccess) {
      console.log("Got token silently through SSO");
      onSuccess();
    }
    return accessToken.accessToken;
  } catch (error) {
    try {
      console.log("Getting token with fallback using Microsoft Authentication Library login dialog");
      const accessToken = await getAccessTokenMSAL(publicClientApp);
      if (onSuccess) {
        console.log("Got token with fallback using Microsoft Authentication Library login dialog");
        onSuccess();
      }
      return accessToken;
    } catch (error) {
      // if both SSO and fallback fail, throw the error to the caller.
      console.log("Could not retrieve token Microsoft Authentication Library login dialog, application can not run");
      throw error;
    }
  }
}

async function getAccessTokenMSAL(publicClientApp: PublicClientApplication): Promise<string> {
  // Create a promise to wrap the dialog callback we need to process later in this function.
  let promise = await new Promise<string>((resolve, reject) => {
    const fullUrl = `${OUTLOOK_ADDIN_HOST}/fallbackauthdialog.html`;
    //https://learn.microsoft.com/en-us/office/dev/add-ins/develop/dialog-api-in-office-add-ins
    // height and width are percentages of the size of the parent Office application, e.g., Outlook, PowerPoint, Excel, Word, etc.
    Office.context.ui.displayDialogAsync(fullUrl, { height: 60, width: 30 }, (result) => {
      console.log("Dialog has initialized. Wiring up events");
      let loginDialog = result.value;
      console.log(loginDialog);
      loginDialog.addEventHandler(
        Office.EventType.DialogMessageReceived,
        (arg: any) => {
          console.log("Message received in processMessage");
          console.log(arg);
          if ("message" in arg) {
            let messageFromDialog = JSON.parse(arg.message);

            if (messageFromDialog.status === "success") {
              // We now have a valid access token.
              loginDialog.close();

              // Configure MSAL to use the signed-in account as the active account for future requests.
              const homeAccount = publicClientApp.getAccountByHomeId(messageFromDialog.accountId);
              if (homeAccount) {
                // homeAccountId = messageFromDialog.accountId; // Track the account id for future silent token requests.
                publicClientApp.setActiveAccount(homeAccount);
              }

              resolve(messageFromDialog.result);
            } else if (messageFromDialog.error === undefined && messageFromDialog.result.errorCode === undefined) {
              // Need to pick the user to use to auth
            } else {
              // Something went wrong with authentication or the authorization of the web application.
              loginDialog.close();
              if (messageFromDialog.error) {
                const error = JSON.stringify(messageFromDialog.error.toString());
                reject(error);
              }
            }
          }
        }
      );
    });
  });
  return promise;
}

Identity Provider

Azure AD / MSA

Source

External (Customer)

microsoft-github-policy-service[bot] commented 1 year ago

This issue requires attention from the MSAL.js team and has not seen activity in 5 days. @hectormmg please follow up.

microsoft-github-policy-service[bot] commented 1 year ago

This issue requires attention from the MSAL.js team and has not seen activity in 5 days. @hectormmg please follow up.

microsoft-github-policy-service[bot] commented 1 year ago

This issue requires attention from the MSAL.js team and has not seen activity in 5 days. @hectormmg please follow up.

microsoft-github-policy-service[bot] commented 1 year ago

This issue requires attention from the MSAL.js team and has not seen activity in 5 days. @hectormmg please follow up.

microsoft-github-policy-service[bot] commented 1 year ago

This issue requires attention from the MSAL.js team and has not seen activity in 5 days. @hectormmg please follow up.

tnorling commented 1 year ago

There are no known issues related to getting accounts in v2 or in v3. If nothing has changed in your code perhaps something changed in your access to local/sessionStorage. That's where I'd start, try debugging to see if the accounts are able to be stored in localstorage and then whether they can be retrieved.

Unfortunately this isn't super actionable for us so I'm closing but feel free to let us know if you have any further questions.