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.
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}`);
}
}