microsoft-authentication-library-for-js icon indicating copy to clipboard operation
microsoft-authentication-library-for-js copied to clipboard

ServerError msal-browser outlook add-in on Android

Open kasperrt opened this issue 1 year ago • 1 comments
trafficstars

Core Library

MSAL.js (@azure/msal-browser)

Core Library Version

3.13.0

Wrapper Library

Not Applicable

Wrapper Library Version

None

Public or Confidential Client?

Public

Description

When trying to initiate login/authentication to get user-tokens in an Outlook add-in on Android, both acquireTokenPopup and loginPopup produces ServerErrors without a lot more info. All is working as it should in both browser, in-app on desktop, and in-app on iOS.

We are initializing the client as seen in the codesnippet, same with how the token-fetching is being done.

Again, there are some very aggressive ways we've been trying now as might see from the above code, but to no avail on any of our approaches. So far, it seems that all the approaches we've had, errors before even trying to trigger a popup to be opened, as the android Outlook app errors immediately, without a popup opening/closing, only showing the page that would be the opener of said popup.

We're at an impass on where to continue now, as we can't seem to figure out any more approaches on what to do next.

Error Message

ServerError

with the most we got out of stack-traces is that it fails on const a = this.nestedAppAuthAdapter.fromBridgeError(n); in NestedAppAuthController.js, in the function acquireTokenInteractive

MSAL Logs

Seeing Android is somewhat impossible to debug, this is the closest we've gotten getting verbose logs.

[Fri, 03 May 2024 14:38:15 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenStart 
[Fri, 03 May 2024 14:38:15 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenFailure 
[Fri, 03 May 2024 14:38:15 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenStart 
[Fri, 03 May 2024 14:38:15 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenFailure 
[Fri, 03 May 2024 14:38:15 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenStart 
[Fri, 03 May 2024 14:38:15 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenFailure 
[Fri, 03 May 2024 14:38:15 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenStart 
[Fri, 03 May 2024 14:38:15 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenFailure
ServerError

Network Trace (Preferrably Fiddler)

  • [ ] Sent
  • [ ] Pending

MSAL Configuration

{
  auth: {
    clientId: import.meta.env.VITE_PISTACHIO_MICROSOFT_CLIENT_ID,
    authority: 'https://login.microsoftonline.com/common',
    supportsNestedAppAuth: true,
  },
  system: {
    loggerOptions: {
      logLevel: LogLevel.Verbose,
      loggerCallback: (_level, message, _containsPii) => {
        this.errorCode.msg += `${message}\n\n`;
        return;
      },
    },
  },
}

Relevant Code Snippets

import {
  PublicClientNext,
  type IPublicClientApplication,
  type AuthenticationResult,
  LogLevel,
  Configuration,
} from '@azure/msal-browser';

export class MicrosoftClient {
  private errorCode: Record<'msg', number | string>;
  private client: IPublicClientApplication | null = null;
  private loginHint = '';
  private userAccount: AuthenticationResult | null = null;

  constructor(errorCode: MicrosoftClient['errorCode']) {
    this.errorCode = errorCode;
  }

  async init() {
    this.errorCode.msg = 'MS-I';

    // Initialize MSAL. MSAL need's a loginHint for when running in a browser.
    const accountType = Office.context.mailbox.userProfile.accountType;
    this.loginHint =
      accountType === 'office365' || accountType === 'outlookCom'
        ? Office.context.mailbox.userProfile.emailAddress
        : '';

    const msalConfig: Configuration = {
    auth: {
      clientId: '__INSERT_CLIENT_ID_HERE__',
      authority: 'https://login.microsoftonline.com/common',
      supportsNestedAppAuth: true,
    },
    system: {
      loggerOptions: {
        logLevel: LogLevel.Verbose,
        loggerCallback: (_level, message, _containsPii) => {
          this.errorCode.msg += `${message}\n\n`;
          return;
        },
      },
    },
  };
    this.client = await PublicClientNext.createPublicClientApplication(msalConfig);

    await this.client?.initialize();
  }

  async getToken() {
    const client = this.client;
    if (!client) {
      throw new Error('Client not initialized');
    }

    this.errorCode.msg = 'MS-TKN-1\n\n';

    const currentAccount = client.getAccountByUsername(this.loginHint);
    const tokenRequest = {
      scopes: ['openid', 'profile', 'User.Read', 'ThreatSubmission.Read', 'Mail.ReadWrite.Shared', 'Mail.Send.Shared'],
      ...(currentAccount?.idTokenClaims?.login_hint && { loginHint: currentAccount?.idTokenClaims?.login_hint }),
      ...(currentAccount?.idTokenClaims?.sid && { sid: currentAccount?.idTokenClaims?.sid }),
      ...(currentAccount && { account: currentAccount }),
    };

    this.errorCode.msg = 'MS-TKN-2\n\n';
    this.userAccount = await client
      ?.acquireTokenSilent(tokenRequest)
      .catch(() => {
        this.errorCode.msg += 'MS-TKN-3\n\n';
        return client.ssoSilent(tokenRequest);
      })
      .catch(() => {
        this.errorCode.msg += 'MS-TKN-4\n\n';
        return client.acquireTokenPopup({
          ...tokenRequest,
        });
      })
      .catch(() => {
        this.errorCode.msg += 'MS-TKN-5 STAGE\n\n';
        return client.loginPopup({
          ...tokenRequest,
        });
      })
      .catch((e) => {
        this.errorCode.msg += `MS-TKN-7-${e}\n\n`;
        throw e;
      });

    this.errorCode.msg = 'MS-TKN-8';
    await client.hydrateCache(this.userAccount, tokenRequest);
  }
}

Office.onReady(async () => {
  const microsoftClient = new MicrosoftClient({msg: 'no-error'});
  await microsoftClient.init();
  const token = await microsoftClient.getToken();

  console.log({ token });
});

Reproduction Steps

  1. Set up an outlook add-in with the scopes ['openid', 'profile', 'User.Read', 'ThreatSubmission.Read', 'Mail.ReadWrite.Shared', 'Mail.Send.Shared']
  2. Publish said add-in to your own AAD-tenant
  3. Add code supplied to the add-ins main.ts file
  4. Run the add-in on an email to start the auth-token flow
  5. See it error

Expected Behavior

To not crash and spit out a ServerError, but instead open a popup like every other environment and platform Outlook runs on.

Identity Provider

Entra ID (formerly Azure AD) / MSA

Browsers Affected (Select all that apply)

Other

Regression

No response

Source

External (Customer)

kasperrt avatar May 03 '24 18:05 kasperrt

@kasperrt have you involved the Android auth team to help here? NAA completely relies on the hub to authenticate and in this case the hub is the native android auth stack. Let me try see if I can pull the right people here.

cc @codexeon do we know who can help here?

sameerag avatar May 07 '24 11:05 sameerag

@kasperrt This issue has been automatically marked as stale because it is marked as requiring author feedback but has not had any activity for 5 days. If your issue has been resolved please let us know by closing the issue. If your issue has not been resolved please leave a comment to keep this open. It will be closed automatically in 7 days if it remains stale.

This has not been solved yet no.

@sameerag I havent been in contact with the Android team now, I assumed the tag from you here should be sufficient as of now?

kasperrt avatar May 13 '24 15:05 kasperrt

@kasperrt This issue has been automatically marked as stale because it is marked as requiring author feedback but has not had any activity for 5 days. If your issue has been resolved please let us know by closing the issue. If your issue has not been resolved please leave a comment to keep this open. It will be closed automatically in 7 days if it remains stale.

This has not been solved yet no.

@sameerag I havent been in contact with the Android team now, I assumed the tag from you here should be sufficient as of now?

Still unsolved.

Do I need to keep bumping this @sameerag every few days to ensure that it doesn't get closed?

kasperrt avatar May 21 '24 07:05 kasperrt