BetterSolutions.com
BetterSolutions.com

Reputation: 777

office-addin-sso with @azure/msal-browser

Is it possible to use office-addin-sso with @azure/msal-browser ?

I would like to:

I have managed to get both the above working and can successfully get the MS Graph access token using just @azure/msal-browser.

Given that we want to use msal-browser/auth code flow with PKCE (and not msal/implicit flow) for the fallback, what would be the most effective way of getting the MS Graph access token in this context.

and given that the office-addin-sso package uses On Behalf Of Flow (requiring a secret and redirect).

Any help/suggestions or guidance would be really appreciated.

Upvotes: 0

Views: 1218

Answers (1)

Ninca Tirtil
Ninca Tirtil

Reputation: 324

I use @azure/msal-browser in the office-addin-sso. My addin is for a single domain and the users are supposed to be logged in on OneDrive so I expect to never need the login via the fallback. I get the token silently from msal and then pass it to MS graph to get an access token. This is the code that does it in the ssoauthhelper.ts:

import * as Msal from '@azure/msal-browser';
export async function getToken_Email() {
  try {
    const msalConfig: Msal.Configuration = {
      auth: {
        clientId: "<your client id>", //This is your client ID
        authority: "https://login.microsoftonline.com/<tenant id>", //The <tenant> in the URL is the tenant ID of the Azure Active Directory (Azure AD) tenant (a GUID), or its tenant domain.
        redirectUri: "https://<your server>/office-js/fallbackauthdialog.html",
        navigateToLoginRequestUrl: false,
      },
      cache: {
        cacheLocation: "localStorage", // Needed to avoid "User login is required" error.
        storeAuthStateInCookie: true, // Recommended to avoid certain IE/Edge issues.
      },
    };

    const msalInstance = new Msal.PublicClientApplication(msalConfig);
    const silentRequest = {
      scopes: ["User.Read", "openid", "profile"]
    };
    let access_token: string;
    try {
      const loginResponse = await msalInstance.ssoSilent(silentRequest);
      access_token = loginResponse.accessToken;
    } catch (err) {
      if (err instanceof Msal.InteractionRequiredAuthError) {
        const loginResponse = await msalInstance.loginPopup(silentRequest).catch(error => {
          // handle error
        });
      } else {
        // handle error
      }
    }

    console.log('silent token response: ' + JSON.stringify(access_token));


    // makeGraphApiCall makes an AJAX call to the MS Graph endpoint. Errors are caught
    // in the .fail callback of that call
    const graph_response: any = await makeGraphApiCall(access_token);
    console.log('graph response: ' + JSON.stringify(graph_response));
  } catch (exception) {
    console.log(exception);
  }
}

export async function makeGraphApiCall(accessToken: string): Promise < any > {
  try {
    const response = await $.ajax({
      type: "GET",
      url: "https://graph.microsoft.com/oidc/userinfo/",
      headers: {
        access_token: accessToken,
        Authorization: 'Bearer ' + accessToken + ' '
      },
      cache: false,
    });
    return response;
  } catch (err) {
    console.log(`Error from Microsoft Graph. \n${err}`);
  }
}

Upvotes: 1

Related Questions