OfficeDev / Office-Add-in-samples

Code samples for Office Add-in development on the Microsoft 365 platform.
MIT License
759 stars 811 forks source link

In SSO Fallback, getAccessTokenMSAL() returns a different user than Office.auth.getAccessToken() #790

Open CBullen2 opened 5 months ago

CBullen2 commented 5 months ago

URL of sample

Office-Add-in-NodeJS-SSO

Describe the bug

My primary Windows login is a Microsoft Personal Account. I also have a Work account linked to it and I can switch between them in the browser and in Excel.

When I start Excel, by default, it uses my Personal Account. When my add-in calls Office.auth.getAccessToken(), I get the JWT for that account.

When my add-in falls back to getAccessMSAL(), I get the JWT for my work account, which is not the account I'm using in Excel.

To Reproduce

Steps to reproduce the behavior:

  1. Create a new Microsoft personal account and log in to Windows with it
  2. In Windows settings, add a work account
  3. Start Excel, note the name in the Window title bar is the personal account
  4. Open the addin, set useSSO = true, run it and check the JWT - notice it's the personal account
  5. set useSSO = false, run it and check the JWT - notice it's the work account

Note that the above might depend on which account(s) are logged in on the browser.

Expected behavior

Both Office.auth.getAccessToken and getAcessTokenMSAL should return the same account, and that should be the one logged in to Excel

Environment

Additional context

Add any other context about the problem here.

AlexJerabek commented 5 months ago

Hi @CBullen2,

Thanks for reporting this. @davidchesnut, could you please investigate?

davidchesnut commented 5 months ago

@CBullen2, thanks for raising this issue. I believe this is a bug in the fallback code of the sample. I believe it's attempting to cache the account info but getting something wrong. I'll put this on the backlog to fix.

CBullen2 commented 5 months ago

Thanks for looking @davidchesnut . I notice that when I go to a web site that needs a login, I usually get a prompt from MSAL that gives me the choice of which account to use for that site (both personal and work accounts are shown as 'Signed in' on that page); it feels like the MSAL fallback may be trying to be too SSO and picking the first account. Ideally, it'd pick the same account that I'm logged into Office with (I raised a semi-related bug in the office.js area that add-ins aren't respecting the selected Excel user account)

davidchesnut commented 5 months ago

I removed the code that attempts to cache the home account. You can see the change here if you want to try it in your code as well. https://github.com/OfficeDev/Office-Add-in-samples/pull/793/files

CBullen2 commented 5 months ago

Thanks for looking, but I don't think that's it, as that would only affect the second time it's called, no?

To repro, I created a new Yeoman JavaScript React addin project, copied all your login code into it and made the index.js try each login and show the result:

import * as React from "react";
import { createRoot } from "react-dom/client";
import { FluentProvider, webLightTheme } from "@fluentui/react-components";
import { getAccessToken } from "../login/loginHelper";  // Your helper function
import { jwtDecode } from "jwt-decode";

Office.onReady(async () => {
  var sso = await getUser(true);
  var msal = await getUser(false);

  root.render(
    <FluentProvider id="Fluent" theme={webLightTheme}>
      <br />
      <br />
      <h3>SSO User: {sso}</h3>
      <h3>MSAL User: {msal}</h3>
    </FluentProvider>
  );
});

async function getUser(useSSO) {
  // Call the wrapper function to use either SSO or MSAL
  // N.B. I changed the MSAL code to return idToken rather than accessToken, so it's consistent
  // (My Azure app is configured to return both auth and id tokens)
  var userToken = await getAccessToken(useSSO);

  // Get the email Id from the token
  var roles = jwtDecode(userToken);
  if (roles != null) return roles["preferred_username"];

  return "Error";
}

I'm logged in to Windows with my Personal account, but logged in the browser (Chrome) with both Personal and Work accounts.

When I start the addin in Excel Desktop, You can see I'm signed in to Excel with the Personal account and have the work account available to switch to. SSO gives me the personal account; MSAL gives me the Work account:

Excel accounts

CBullen2 commented 5 months ago

Normally when I'm logging in to a web site, the MSAL dialogs give me a popup asking which account I want to use; this code sample doesn't give me such a popup, it just automatically signs me in with the Work account (or maybe the first alphabetically?).

davidchesnut commented 5 months ago

Hi @CBullen2, thanks for that info. I'm still looking into this.