Enable SSO in an Office Add-in using nested app authentication (preview)
You can use the MSAL.js library (version 3.11 and later) with nested app authentication to use SSO from your Office Add-in. Using nested app authentication offers several advantages over the On-Behalf-Of (OBO) flow.
- You only need to use the MSAL.js library and don’t need the
getAccessToken
function in Office.js. - You can call services such as Microsoft Graph with an access token from your client code as an SPA. There’s no need for a middle-tier server.
- You can use incremental and dynamic consent for scopes.
- You don't need to preauthorize your hosts (For example, Teams, Office) to call your endpoints.
Important
Nested app authentication (NAA) is currently in preview. To try this feature, join the Microsoft 365 Insider Program (https://insider.microsoft365.com/join) and choose the Beta Channel. Don't use NAA in production add-ins. We invite you to try out NAA in test or development environments and welcome feedback on your experience through GitHub (see the Feedback section at the end of this page).
Register your single-page application
You’ll need to create a Microsoft Azure App registration for your add-in on the Azure portal. The app registration must have at minimum:
- A name
- A supported account type
- An SPA redirect
If your add-in requires additional app registration beyond NAA and SSO, see Single-page application: App registration.
Add a trusted broker through SPA redirect
To enable NAA, your app registration must include a specific redirect URI to indicate to the Microsoft identity platform that your add-in allows itself to be brokered by supported hosts. The redirect URI of the application must be of type Single Page Application and conform to the following scheme.
brk-multihub://your-add-in-domain
Trusted broker groups are dynamic by design and can be updated in the future to include additional hosts where your add-in may use NAA flows. Currently the brk-multihub group includes Office Word, Excel, PowerPoint, Outlook, and Teams (for when Office is activated inside).
Configure MSAL config to use NAA
Configure your add-in to use NAA by setting the supportsNestedAppAuth
property to true in your MSAL configuration. This enables MSAL to use APIs on its native application host (for example, Outlook) to acquire tokens for your application. If you don't set this property, MSAL uses the default JavaScript-based implementation to acquire tokens for your application, which may lead to unexpected auth prompts and unsatisfiable conditional access policies when running inside of a webview.
// Configuration for NAA.
const msalConfig = {
auth: {
clientId: "Enter_the_Application_Id_Here",
authority: "https://login.microsoftonline.com/common",
supportsNestedAppAuth: true
}
}
Initialize the public client application
Next, you need to initialize MSAL and get an instance of the public client application. This is used to get access tokens when needed. It's recommended to create the public client application in the Office.onReady
method.
let pca = undefined;
// Initialize the publice client application
Office.onReady(async (info) => {
pca = await msalBrowser.PublicClientNext.createPublicClientApplication(msalConfig);
});
Acquire your first token
The tokens acquired by MSAL.js via NAA will be issued for your Azure app registration ID. In this code sample, you acquire a token for the Microsoft Graph API. If the user has an active session with Microsoft Entra ID the token is acquired silently. If not, the library prompts the user to sign in interactively. The token is then used to call the Microsoft Graph API.
The following steps show the pattern to use for acquiring a token.
- Specify your scopes. NAA supports incremental and dynamic consent so always request the minimum scopes needed for your code to complete its task.
- Call
acquireTokenSilent
. This will get the token without requiring user interaction. - If
acquireTokenSilent
fails, callacquireTokenPopup
to display an interactive dialog for the user.acquireTokenSilent
can fail if the token expired, or the user has not yet consented to all of the requested scopes.
async function run() {
// Specify minimum scopes needed for the access token.
const tokenRequest = {
scopes: ["User.Read", "openid", "profile"],
loginHint: myloginHint
}
try {
const userAccount = await pca.acquireTokenSilent(tokenRequest);
// Call your API with the token.
makeMSGraphCall(userAccount.accessToken);
} catch (error) {
// Acquire token silent failure. Send an interactive request via popup.
try {
const userAccount = pca.acquireTokenPopup(tokenRequest);
// Call your API with the token.
makeMSGraphCall(userAccount.accessToken);
} catch (popupError) {
// Acquire token interactive failure.
console.log(popupError);
}
}
}
Call an API
After acquiring the token, use it to call an API. The following example shows how to call the Microsoft Graph API by calling fetch
with the token attached in the Authorization header.
async function makeMSGraphCall(accessToken) {
const requestString = "https://graph.microsoft.com/v1.0/me";
const headersInit = { 'Authorization': accessToken };
const requestInit = { 'headers': headersInit }
// Make REST call to MS Graph.
const result = await fetch(requestString, requestInit);
if (result.ok) {
const data = await result.text();
console.log(data);
document.getElementById("userInfo").innerText = data;
} else {
// Likely an MS Graph error if result was not ok.
// Error details are in the body.
const response = await result.text();
console.log(response);
}
}
What is nested app authentication
Nested app authentication enables SSO for applications that are nested inside of supported first-party applications. For example, Excel on Windows runs your add-in inside a webview. In this scenario, your add-in is a nested application running inside Excel, which is the host. NAA also supports nested apps in Teams. For example, if a Teams tab is hosting Excel, and your add-in is loaded, it is nested inside Excel, which is also nested inside Teams. Again, NAA supports this nested scenario and you can access SSO to get user identity and access tokens of the signed in user.
NAA supported accounts and hosts
NAA supports both Microsoft Accounts and Microsoft Entra ID (work/school) identities. It doesn’t support B2C scenarios. For preview, NAA is supported in Office on Windows and on Mac. For GA, NAA will also support Office on the web, and Outlook mobile on Android and on iOS.
Best practices
The following are some best practices when using MSAL.js with NAA.
Use silent authentication whenever possible
MSAL.js provides the acquireTokenSilent
method that handles token renewal by making silent token requests without prompting the user. The method first looks for a valid cached token. If it doesn't find one, the library makes the silent request to Microsoft Entra ID and if there's an active user session, a fresh token is returned.
In certain cases, the acquireTokenSilent
method's attempt to get the token fails. Some examples of this are when there's an expired user session with Microsoft Entra ID or a password change by the user, which requires user interaction. When the acquireTokenSilent fails, you need to call the interactive acquireTokenPopup
token method.
Have a fallback when NAA isn't supported
While we strive to provide a high-degree of compatibility with these flows across the Microsoft ecosystem, your application may appear in downlevel/legacy clients that haven't been updated to support NAA. In these cases, your application won't support seamless SSO and you may need to invoke special APIs for interacting with the user to open authentication dialogs. For more information, see Authenticate and authorize with the Office dialog API.
MSAL.js APIs supported by NAA
The following table shows which APIs are supported when NAA is enabled in the MSAL config.
Method | Supported by NAA |
---|---|
acquireTokenByCode | NO (throws exception) |
acquireTokenPopup | YES |
acquireTokenRedirect | NO (throws exception) |
acquireTokenSilent | YES |
addEventCallback | YES |
addPerformanceCallback | YES |
disableAccountStorageEvents | NO (throws exception) |
enableAccountStorageEvents | NO (throws exception) |
getAccountByHomeId | YES |
getAccountByLocalId | YES |
getAccountByUsername | YES |
getActiveAccount | YES |
getAllAccounts | YES |
getConfiguration | YES |
getLogger | YES |
getTokenCache | NO (throws exception) |
handleRedirectPromise | NO |
initialize | YES |
initializeWrapperLibrary | YES |
loginPopup | YES |
loginRedirect | NO (throws exception) |
logout | NO (throws exception) |
logoutPopup | NO (throws exception) |
logoutRedirect | NO (throws exception) |
removeEventCallback | YES |
removePerformanceCallback | YES |
setActiveAccount | NO |
setLogger | YES |
ssoSilent | YES |
Security reporting
If you find a security issue with our libraries or services, report the issue to secure@microsoft.com with as much detail as you can provide. Your submission may be eligible for a bounty through the Microsoft Bounty program. Don't post security issues to GitHub or any other public site. We'll contact you shortly after receiving your issue report. We encourage you to get new security incident notifications by visiting Microsoft technical security notifications to subscribe to Security Advisory Alerts.
Code samples
Sample name | Description |
---|---|
Office Add-in with SSO using nested app authentication | Shows how to use MSAL.js nested app authentication (NAA) in an Office Add-in to access Microsoft Graph APIs for the signed-in user. The sample displays the signed-in user's name and email. It also inserts the names of files from the user's Microsoft OneDrive account into the document. |
Outlook add-in with SSO using nested app authentication | Shows how to use MSAL.js nested app authentication (NAA) in an Outlook Add-in to access Microsoft Graph APIs for the signed-in user. The sample displays the signed-in user's name and email. It also inserts the names of files from the user's Microsoft OneDrive account into a new message body. |
Office Add-ins
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for