Skip to content

Commit e5fa62a

Browse files
authored
consume auth context API and add logging (#767)
1 parent d57b576 commit e5fa62a

File tree

2 files changed

+100
-25
lines changed

2 files changed

+100
-25
lines changed

Samples/auth/Outlook-Add-in-SSO-NAA/src/taskpane/authConfig.ts

Lines changed: 98 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,107 @@
33

44
/* This file provides MSAL auth configuration to get access token through nested app authentication. */
55

6-
/* global console */
6+
/* global console, Office */
77

8-
import { PublicClientNext, type IPublicClientApplication } from "@azure/msal-browser";
8+
import {
9+
type AccountInfo,
10+
PublicClientNext,
11+
type IPublicClientApplication,
12+
Configuration,
13+
LogLevel,
14+
} from "@azure/msal-browser";
915

1016
export { AccountManager };
1117

18+
interface AuthContext {
19+
loginHint: string;
20+
userPrincipalName: string;
21+
userObjectId: string;
22+
tenantId: string;
23+
}
24+
1225
const applicationId = "Enter_the_Application_Id_Here";
1326

14-
const msalConfig = {
15-
auth: {
16-
clientId: applicationId,
17-
authority: "https://login.microsoftonline.com/common",
18-
supportsNestedAppAuth: true,
19-
},
20-
};
27+
function getMsalConfig(enableDebugLogging: boolean) {
28+
const msalConfig: Configuration = {
29+
auth: {
30+
clientId: applicationId,
31+
authority: "https://login.microsoftonline.com/common",
32+
supportsNestedAppAuth: true,
33+
},
34+
system: {},
35+
};
36+
if (enableDebugLogging) {
37+
msalConfig.system.loggerOptions = {
38+
logLevel: LogLevel.Verbose,
39+
loggerCallback: (level: LogLevel, message: string) => {
40+
switch (level) {
41+
case LogLevel.Error:
42+
console.error(message);
43+
return;
44+
case LogLevel.Info:
45+
console.info(message);
46+
return;
47+
case LogLevel.Verbose:
48+
console.debug(message);
49+
return;
50+
case LogLevel.Warning:
51+
console.warn(message);
52+
return;
53+
}
54+
},
55+
piiLoggingEnabled: true,
56+
};
57+
}
58+
return msalConfig;
59+
}
2160

2261
// Encapsulate functions for getting user account and token information.
2362
class AccountManager {
24-
loginHint: string = "";
25-
pca: IPublicClientApplication | undefined = undefined;
63+
private pca: IPublicClientApplication | undefined = undefined;
64+
private account: AccountInfo | undefined = undefined;
65+
private loginHint: string | undefined = undefined;
2666

2767
// Initialize MSAL public client application.
28-
async initialize(loginHint: string) {
29-
this.loginHint = loginHint;
30-
this.pca = await PublicClientNext.createPublicClientApplication(msalConfig);
68+
async initialize() {
69+
// If auth is not working, enable debug logging to help diagnose.
70+
this.pca = await PublicClientNext.createPublicClientApplication(getMsalConfig(false));
71+
72+
// Initialize account by matching account known by Outlook with MSAL.js
73+
let username = "";
74+
let tenantId = "";
75+
let localAccountId = "";
76+
try {
77+
const authContext: AuthContext = await Office.auth.getAuthContext();
78+
username = authContext.userPrincipalName;
79+
tenantId = authContext.tenantId;
80+
localAccountId = authContext.userObjectId;
81+
this.loginHint = authContext.loginHint || authContext.userPrincipalName;
82+
} catch {
83+
// Intentionally empty catch block.
84+
}
85+
86+
if (!this.loginHint) {
87+
const accountType = Office.context.mailbox.userProfile.accountType;
88+
this.loginHint =
89+
accountType === "office365" || accountType === "outlookCom"
90+
? Office.context.mailbox.userProfile.emailAddress
91+
: "";
92+
}
93+
94+
// Try to use auth context to find account
95+
this.account = this.pca.getAllAccounts().find((account) => {
96+
return (
97+
(localAccountId && account.localAccountId?.toLowerCase() === localAccountId.toLowerCase()) ||
98+
(account.username &&
99+
account.username === username.toLowerCase() &&
100+
account.tenantId?.toLowerCase() === tenantId)
101+
);
102+
});
31103
}
32104

33105
/**
34-
*
106+
*
35107
* @param scopes the minimum scopes needed.
36108
* @returns An access token.
37109
*/
@@ -41,10 +113,10 @@ class AccountManager {
41113
}
42114

43115
/**
44-
*
116+
*
45117
* Uses MSAL and nested app authentication to get the user account from Office SSO.
46118
* This demonstrates how to work with user identity from the token.
47-
*
119+
*
48120
* @param scopes The minimum scopes needed.
49121
* @returns The user account data (including identity).
50122
*/
@@ -57,27 +129,31 @@ class AccountManager {
57129
const tokenRequest = {
58130
scopes: scopes,
59131
loginHint: this.loginHint,
132+
account: this.account,
60133
};
61134

62135
try {
63136
console.log("Trying to acquire token silently...");
64137

65138
//acquireTokenSilent requires an active account. Check if one exists, otherwise use ssoSilent.
66-
const account = this.pca.getActiveAccount();
67-
const userAccount = account ? await this.pca.acquireTokenSilent(tokenRequest) : await this.pca.ssoSilent(tokenRequest);
139+
const authResult = this.account
140+
? await this.pca.acquireTokenSilent(tokenRequest)
141+
: await this.pca.ssoSilent(tokenRequest);
142+
this.account = authResult.account;
68143

69144
console.log("Acquired token silently.");
70-
return userAccount;
145+
return authResult;
71146
} catch (error) {
72147
console.log(`Unable to acquire token silently: ${error}`);
73148
}
74149

75150
// Acquire token silent failure. Send an interactive request via popup.
76151
try {
77152
console.log("Trying to acquire token interactively...");
78-
const userAccount = await this.pca.acquireTokenPopup(tokenRequest);
153+
const authResult = await this.pca.acquireTokenPopup(tokenRequest);
154+
this.account = authResult.account;
79155
console.log("Acquired token interactively.");
80-
return userAccount;
156+
return authResult;
81157
} catch (popupError) {
82158
// Acquire token interactive failure.
83159
console.log(`Unable to acquire token interactively: ${popupError}`);

Samples/auth/Outlook-Add-in-SSO-NAA/src/taskpane/taskpane.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ Office.onReady((info) => {
2828
}
2929

3030
// Initialize MSAL. MSAL need's a loginHint for when running in a browser.
31-
const accountType = Office.context.mailbox.userProfile.accountType;
32-
const loginHint = (accountType === "office365" || accountType === "outlookCom") ? Office.context.mailbox.userProfile.emailAddress : "";
33-
accountManager.initialize(loginHint);
31+
32+
accountManager.initialize();
3433
}
3534
});
3635

0 commit comments

Comments
 (0)