Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 47 additions & 51 deletions docs/develop/enable-nested-app-authentication-in-your-add-in.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
title: Enable single sign-on in an Office Add-in with nested app authentication
description: Learn how to enable SSO in an Office Add-in with nested app authentication.
ms.date: 07/14/2025
ms.date: 10/20/2025
ms.topic: how-to
ms.localizationpriority: high
---

# Enable single sign-on in an Office Add-in with nested app authentication

You can use the MSAL.js library with nested app authentication to use single sign-on (SSO) from your Office Add-in. Using nested app authentication (NAA) offers several advantages over the On-Behalf-Of (OBO) flow.
Use the MSAL.js library with nested app authentication to enable single sign-on (SSO) from your Office Add-in. Using nested app authentication (NAA) 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.
Expand All @@ -17,19 +17,7 @@ You can use the MSAL.js library with nested app authentication to use single sig

## NAA supported accounts and hosts

NAA supports both Microsoft Accounts and Microsoft Entra ID (work/school) identities. It doesn't support [Azure Active Directory B2C](/azure/active-directory-b2c/overview) for business-to-consumer identity management scenarios. The following table explains the current support by platform. Platforms listed as generally available (GA) are ready for production usage in your add-in.

| Application | Web | Windows | Mac | iOS/iPad | Android |
|-------------|------------|------------------------------------------------------|------------|--------------------|----------------|
| Excel | In preview | In preview | In preview | In preview on iPad | Not applicable |
| Outlook | GA | GA | GA | GA (iOS) | GA |
| PowerPoint | In preview | In preview | In preview | In preview on iPad | Not applicable |
| Word | In preview | In preview | In preview | In preview on iPad | Not applicable |

> [!IMPORTANT]
> To use NAA on platforms that are still in preview (Word, Excel, and PowerPoint), join the [Microsoft 365 Insider Program](https://aka.ms/MSFT365InsiderProgram) and choose **Current Channel (Preview)**. Don't use NAA in production add-ins for any preview platforms. 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).

For information on using NAA in Microsoft Teams, see [Nested app authentication in Microsoft Teams](/microsoftteams/platform/concepts/authentication/nested-authentication).
NAA supports both Microsoft Accounts and Microsoft Entra ID (work/school) identities. It doesn't support [Azure Active Directory B2C](/azure/active-directory-b2c/overview) for business-to-consumer identity management scenarios. For more information on NAA requirements, see [Nested app auth requirement set](/javascript/api/requirement-sets/common/nested-app-auth-requirement-sets).

## Register your single-page application

Expand Down Expand Up @@ -61,16 +49,12 @@ Configure your add-in to use NAA by calling the `createNestablePublicClientApp

The following steps show how to enable NAA in the `taskpane.js` or `taskpane.ts` file in a project built with `yo office` (**Office Add-in Task Pane** project).

1. Add the `@azure/msal-browser` package to the `dependencies` section of the `package.json` file for your project. For more information on this package, see [Microsoft Authentication Library for JavaScript (MSAL.js) for Browser-Based Single-Page Applications](https://www.npmjs.com/package/%40azure/msal-browser). We recommend using the latest version of the package (at time of the last article update it was 3.26.0).
1. Add the `@azure/msal-browser` package to the `dependencies` section of the `package.json` file for your project. For more information on this package, see [Microsoft Authentication Library for JavaScript (MSAL.js) for Browser-Based Single-Page Applications](https://www.npmjs.com/package/%40azure/msal-browser). To install the latest version, run the following command.

```json
"dependencies": {
"@azure/msal-browser": "^3.27.0",
...
```command line
npm install @azure/msal-browser
```

1. Save and run `npm install` to install `@azure/msal-browser`.

1. Add the following code to the top of the `taskpane.js` or `taskpane.ts` file. This will import the MSAL browser library.

```JavaScript
Expand Down Expand Up @@ -115,7 +99,7 @@ The following steps show the pattern to use for acquiring a token.
1. Call `acquireTokenSilent`. This will get the token without requiring user interaction.
1. If `acquireTokenSilent` fails, call `acquireTokenPopup` 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.

The following code shows how to implement this authentication pattern in your own project.
The following code shows how to implement this authentication pattern in your own project. Note that it obtains the login hint if running on Excel, Word, or PowerPoint for web. The login hint is required later in this code for these platforms.

1. Replace the `run` function in `taskpane.js` or `taskpane.ts` with the following code. The code specifies the minimum scopes needed to read the user's files.

Expand All @@ -125,7 +109,15 @@ The following code shows how to implement this authentication pattern in your ow
const tokenRequest = {
scopes: ["Files.Read", "User.Read", "openid", "profile"],
};
let accessToken = null;
let loginHint;
// If running on Excel, Word, or PowerPoint for web, a login hint is needed for SSO.
if ((Office.context.platform === Office.PlatformType.OfficeOnline) && (Office.context.host !== Office.HostType.Outlook)) {
const authCtx = await Office.auth.getAuthContext();
loginHint = authCtx.userPrincipalName;
}

let accessToken;
let authResult;

// TODO 1: Call acquireTokenSilent.

Expand All @@ -143,12 +135,19 @@ The following code shows how to implement this authentication pattern in your ow

1. Replace `TODO 1` with the following code. This code calls `acquireTokenSilent` to get the access token.

About the following code, note that it checks for a login hint. Excel, Word, and PowerPoint for web require calling **ssoSilent** with the login hint to successfully complete SSO.

```JavaScript
try {
console.log("Trying to acquire token silently...");
const userAccount = await pca.acquireTokenSilent(tokenRequest);
console.log("Acquired token silently.");
accessToken = userAccount.accessToken;
console.log("Trying to acquire token silently...");
if (loginHint) {
tokenRequest["loginHint"] = loginHint;
authResult = await pca.ssoSilent(tokenRequest);
} else {
authResult = await pca.acquireTokenSilent(tokenRequest);
}
console.log("Acquired token silently.");
accessToken = authResult.accessToken;
} catch (error) {
console.log(`Unable to acquire token silently: ${error}`);
}
Expand All @@ -157,25 +156,25 @@ The following code shows how to implement this authentication pattern in your ow
1. Replace `TODO 2` with the following code. This code checks if the access token is acquired. If not it attempts to interactively get the access token by calling `acquireTokenPopup`.

```javascript
if (accessToken === null) {
// Acquire token silent failure. Send an interactive request via popup.
try {
console.log("Trying to acquire token interactively...");
const userAccount = await pca.acquireTokenPopup(tokenRequest);
console.log("Acquired token interactively.");
accessToken = userAccount.accessToken;
} catch (popupError) {
// Acquire token interactive failure.
console.log(`Unable to acquire token interactively: ${popupError}`);
}
if (!accessToken) {
// Acquire token silent failure. Send an interactive request via popup.
try {
console.log("Trying to acquire token interactively...");
authResult = await pca.acquireTokenPopup(tokenRequest);
console.log("Acquired token interactively.");
accessToken = authResult.accessToken;
} catch (popupError) {
// Acquire token interactive failure.
console.log(`Unable to acquire token interactively: ${popupError}`);
}
}
```

1. Replace `TODO 3` with the following code. If both silent and interactive sign-in failed, log the error and return.

```javascript
// Log error if both silent and popup requests failed.
if (accessToken === null) {
if (!accessToken) {
console.error(`Unable to acquire access token.`);
return;
}
Expand All @@ -192,18 +191,18 @@ After acquiring the token, use it to call an API. The following example shows ho
const response = await fetch(
`https://graph.microsoft.com/v1.0/me/drive/root/children?$select=name&$top=10`,
{
headers: { Authorization: accessToken },
headers: { Authorization: `Bearer ${accessToken}` },
}
);

if (response.ok) {
// Write file names to the console.
const data = await response.json();
const names = data.value.map((item) => item.name);

// Be sure the taskpane.html has an element with Id = item-subject.
const label = document.getElementById("item-subject");

// Write file names to task pane and the console.
const nameText = names.join(", ");
if (label) label.textContent = nameText;
Expand Down Expand Up @@ -232,21 +231,14 @@ In certain cases, the `acquireTokenSilent` method's attempt to get the token f

### 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 add-in may be loaded in an older Office host that does not support NAA. In these cases, your add-in won't support seamless SSO and you may need to fall back to an alternate method of authenticating the user. In general you'll want to use the MSAL SPA authentication pattern with the [Office JS dialog API](auth-with-office-dialog-api.md).
While we strive to provide a high-degree of compatibility with these flows across the Microsoft ecosystem, your add-in may be loaded in an older Office host that does not support NAA. In these cases, your add-in won't support seamless SSO and you may need to fall back to an alternate method of authenticating the user. Refer to the [code samples](#code-samples) in this article for samples that show how to handle a fallback scenario.

Use the following code to check if NAA is supported when your add-in loads.

```javascript
Office.context.requirements.isSetSupported("NestedAppAuth", "1.1");
```

For more information, see the following resources.

- [Outlook sample: How to fall back and support Internet Explorer 11](https://github.com/OfficeDev/Office-Add-in-samples/blob/main/Samples/auth/Outlook-Add-in-SSO-NAA-IE/README.md)
- [Authenticate and authorize with the Office dialog API](/office/dev/add-ins/develop/auth-with-office-dialog-api).
- [Microsoft identity sample for SPA and JavaScript](https://github.com/Azure-Samples/ms-identity-javascript-tutorial/blob/main/2-Authorization-I/1-call-graph/README.md)
- [Microsoft identity samples for various app types and frameworks](/entra/identity-platform/sample-v2-code?tabs=apptype)

## MSAL.js APIs supported by NAA

The following table shows which APIs are supported when NAA is enabled in the MSAL config.
Expand Down Expand Up @@ -301,3 +293,7 @@ If you find a security issue with our libraries or services, report the issue to

- [NAA FAQ](https://aka.ms/NAAFAQ)
- [Nested app authentication in Microsoft Teams](/microsoftteams/platform/concepts/authentication/nested-authentication).
- [Outlook sample: How to fall back and support Internet Explorer 11](https://github.com/OfficeDev/Office-Add-in-samples/blob/main/Samples/auth/Outlook-Add-in-SSO-NAA-IE/README.md)
- [Authenticate and authorize with the Office dialog API](/office/dev/add-ins/develop/auth-with-office-dialog-api).
- [Microsoft identity sample for SPA and JavaScript](https://github.com/Azure-Samples/ms-identity-javascript-tutorial/blob/main/2-Authorization-I/1-call-graph/README.md)
- [Microsoft identity samples for various app types and frameworks](/entra/identity-platform/sample-v2-code?tabs=apptype)
4 changes: 3 additions & 1 deletion docs/outlook/faq-nested-app-auth-outlook-legacy-tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Nested app authentication and Outlook legacy tokens deprecation FAQ
ms.service: microsoft-365
ms.subservice: add-ins
ms.topic: faq
ms.date: 10/01/2025
ms.date: 10/14/2025
---

# Nested app authentication and Outlook legacy tokens deprecation FAQ
Expand Down Expand Up @@ -32,6 +32,8 @@ The general availability (GA) date for NAA depends on which channel you're using
| January 2025 | NAA is GA in Semi-Annual Channel Version 2408 (Build 17928.20392). |
| June 2025 | NAA is GA in Semi-Annual Extended Channel Version 2408 (Build 17928.20604). |

For more information on NAA requirements, see [Nested app auth requirement set](/javascript/api/requirement-sets/common/nested-app-auth-requirement-sets).

### Are COM Add-ins affected by the deprecation of legacy Exchange Online tokens?

It's very unlikely any COM add-ins are affected by the deprecation of legacy Exchange Online tokens. Outlook web add-ins are primarily affected because they can use Office.js APIs that rely on Exchange tokens. For more information, see [How do I know if my Outlook add-in relies on legacy tokens?](#how-do-i-know-if-my-outlook-add-in-relies-on-legacy-tokens). The Exchange tokens are used to access Exchange Web Services (EWS) or Outlook REST APIs, both of which are also deprecated.
Expand Down