Description
Core Library
MSAL.js (@azure/msal-browser)
Core Library Version
3.21.0
Wrapper Library
Not Applicable
Wrapper Library Version
None
Public or Confidential Client?
Public
Description
Our Motivation for Using MSAL-Browser:
We encountered issues with SSO token retrieval using the OBO flow due to new third-party cookie restrictions in Safari, Firefox, and, most recently, in Chrome's incognito mode. As it is essential for our Outlook add-in to securely retrieve the SSO token, we decided to implement token retrieval using Nested App Authentication, even though it is currently marked as a preview feature. Our decision was based on information indicating that this approach should resolve the issue (source 1, source 2).
The Problem:
After implementing the solution according to the documentation, we encountered errors during both silent and interactive token retrieval, as shown below. We primarily need to acquire the token within the onMessageSend handler when an email is being sent. However, we also attempted to acquire the token within the task pane (as we are aware of potential issues with popups in event-executed code) and encountered the same results. Our add-in’s JavaScript files are hosted on the Azure CDN, where we have configured the CORS headers as recommended in this issue, but this did not resolve the problem.
Important Facts:
- Our app registration is configured correctly according to the documentation.
- Occasionally, we are able to retrieve the token, which indicates that the process can work, but it fails most of the time.
Questions:
- Could you please advise whether the issue lies within your implementation, or if there might be a misunderstanding or misconfiguration on our side?
- Is there a reliable method to retrieve an SSO token in any environment, regardless of cookie restrictions or popup blockers?
Error Message
We get this error while trying to get token silently:
Unable to acquire NAA token silently: InteractionRequiredAuthError: login_required: AADSTS50058: A silent sign-in request was sent but no user is signed in. The cookies used to represent the user's session were not sent in the request to Azure AD. This can happen if the user is using Internet Explorer or Edge, and the web app sending the silent sign-in request is in different IE security zone than the Azure AD endpoint (login.microsoftonline.com). Trace ID: 025d5ec5-ee76-4c1a-a30c-09e4285a7600 Correlation ID: 01919457-542e-7b2f-a69a-a691c421d70b Timestamp: 2024-08-27 14:57:17Z
customLogMethod @ logger.ts:41
error @ logger.ts:139
_callee4$ @ ssoTokenHelper.ts:96
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_throw @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_tryAcquireTokenSilent @ ssoTokenHelper.ts:98
tryAcquireTokenSilent @ ssoTokenHelper.ts:90
_callee3$ @ ssoTokenHelper.ts:81
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoTokenFromNAA @ ssoTokenHelper.ts:88
getSsoTokenFromNAA @ ssoTokenHelper.ts:38
_callee2$ @ ssoTokenHelper.ts:24
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoToken @ ssoTokenHelper.ts:36
getSsoToken @ ssoTokenHelper.ts:16
_callee$ @ apiHelper.ts:18
tryCatch @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
asyncGeneratorStep @ apiHelper.ts:2
_next @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
sendApiRequest @ apiHelper.ts:9
_callee$ @ emailHandling.ts:81
tryCatch @ emailHandling.ts:2
(anonymous) @ emailHandling.ts:2
(anonymous) @ emailHandling.ts:2
asyncGeneratorStep @ emailHandling.ts:2
_next @ emailHandling.ts:2
(anonymous) @ emailHandling.ts:2
(anonymous) @ emailHandling.ts:2
_evaluateMessage @ emailHandling.ts:93
evaluateMessage @ emailHandling.ts:80
_callee$ @ events.ts:54
tryCatch @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
_onItemSendHandlerInner @ events.ts:73
onItemSendHandlerInner @ events.ts:44
_callee8$ @ events.ts:254
tryCatch @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
_onItemSendHandler @ events.ts:258
onItemSendHandler @ events.ts:195
(anonymous) @ outlook-web-16.01.js:20
setTimeout
a._processAppCommandInvocation @ outlook-web-16.01.js:20
fireEvent @ outlook-web-16.01.js:20
onEvent @ outlook-web-16.01.js:20
(anonymous) @ outlook-web-16.01.js:20
M @ outlook-web-16.01.js:20
And then, when we fallback to get the token interactively, we get:
Unable to acquire NAA token interactively: ServerError: user_cancelled: User cancelled the flow.
customLogMethod @ logger.ts:41
error @ logger.ts:139
_callee5$ @ ssoTokenHelper.ts:105
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_throw @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_tryAcquireTokenPopup @ ssoTokenHelper.ts:107
tryAcquireTokenPopup @ ssoTokenHelper.ts:100
_callee3$ @ ssoTokenHelper.ts:87
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoTokenFromNAA @ ssoTokenHelper.ts:88
getSsoTokenFromNAA @ ssoTokenHelper.ts:38
_callee2$ @ ssoTokenHelper.ts:24
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoToken @ ssoTokenHelper.ts:36
getSsoToken @ ssoTokenHelper.ts:16
_callee$ @ apiHelper.ts:18
tryCatch @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
asyncGeneratorStep @ apiHelper.ts:2
_next @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
sendApiRequest @ apiHelper.ts:9
_callee$ @ emailHandling.ts:81
tryCatch @ emailHandling.ts:2
(anonymous) @ emailHandling.ts:2
(anonymous) @ emailHandling.ts:2
asyncGeneratorStep @ emailHandling.ts:2
_next @ emailHandling.ts:2
(anonymous) @ emailHandling.ts:2
(anonymous) @ emailHandling.ts:2
_evaluateMessage @ emailHandling.ts:93
evaluateMessage @ emailHandling.ts:80
_callee$ @ events.ts:54
tryCatch @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
_onItemSendHandlerInner @ events.ts:73
onItemSendHandlerInner @ events.ts:44
_callee8$ @ events.ts:254
tryCatch @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
_onItemSendHandler @ events.ts:258
onItemSendHandler @ events.ts:195
(anonymous) @ outlook-web-16.01.js:20
setTimeout
a._processAppCommandInvocation @ outlook-web-16.01.js:20
fireEvent @ outlook-web-16.01.js:20
onEvent @ outlook-web-16.01.js:20
(anonymous) @ outlook-web-16.01.js:20
M @ outlook-web-16.01.js:20
events_beta.js:1916 [Safetica]: Send handler failed with error TimeoutError: Operation timed out
customLogMethod @ logger.ts:41
error @ logger.ts:139
_callee6$ @ events.ts:126
tryCatch @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
_handleSendError @ events.ts:154
handleSendError @ events.ts:125
_callee8$ @ events.ts:256
tryCatch @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
asyncGeneratorStep @ events.ts:2
_throw @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
Promise.then
asyncGeneratorStep @ events.ts:2
_next @ events.ts:2
(anonymous) @ events.ts:2
(anonymous) @ events.ts:2
_onItemSendHandler @ events.ts:258
onItemSendHandler @ events.ts:195
(anonymous) @ outlook-web-16.01.js:20
setTimeout
a._processAppCommandInvocation @ outlook-web-16.01.js:20
fireEvent @ outlook-web-16.01.js:20
onEvent @ outlook-web-16.01.js:20
(anonymous) @ outlook-web-16.01.js:20
M @ outlook-web-16.01.js:20
Ultimately we have another fallback implemented, when NAA does not work, to at least try the old OBO flow. Then we get:
ssoTokenHelper.ts:32 Uncaught (in promise) AccessDeniedError: Do Office není nikdo přihlášený. Před odesláním se přihlaste.
at _callee2$ (ssoTokenHelper.ts:32:11)
at tryCatch (ssoTokenHelper.ts:2:1)
at Generator.<anonymous> (ssoTokenHelper.ts:2:1)
at Generator.throw (ssoTokenHelper.ts:2:1)
at asyncGeneratorStep (ssoTokenHelper.ts:2:1)
at _throw (ssoTokenHelper.ts:2:1)
_callee2$ @ ssoTokenHelper.ts:32
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_throw @ ssoTokenHelper.ts:2
Promise.catch
sendLogs @ justificationInput.tsx:123
(anonymous) @ useARIAButtonProps.js:39
(anonymous) @ useEventCallback.js:26
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291
executeDispatch @ react-dom.development.js:9041
processDispatchQueueItemsInOrder @ react-dom.development.js:9073
processDispatchQueue @ react-dom.development.js:9086
dispatchEventsForPlugins @ react-dom.development.js:9097
(anonymous) @ react-dom.development.js:9288
batchedUpdates$1 @ react-dom.development.js:26179
batchedUpdates @ react-dom.development.js:3991
dispatchEventForPluginEventSystem @ react-dom.development.js:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465
dispatchEvent @ react-dom.development.js:6457
dispatchDiscreteEvent @ react-dom.development.js:6430
MSAL Logs
logger.ts:41 [Safetica]: Creating NPCA for SSO retrieval
ssoTokenHelper.ts:62 [Wed, 28 Aug 2024 10:15:29 GMT] : [] : @azure/[email protected] : Info - Nested App Auth Bridge available: true
ssoTokenHelper.ts:65 [Wed, 28 Aug 2024 10:15:29 GMT] : [] : @azure/[email protected] : Verbose - BrowserCrypto: modern crypto interface available
logger.ts:41 [Safetica]: Getting SSO from NAA silently
logger.ts:41 [Safetica]: Getting SSO from NAA silently
ssoTokenHelper.ts:62 [Wed, 28 Aug 2024 10:15:29 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenStart
ssoTokenHelper.ts:65 [Wed, 28 Aug 2024 10:15:29 GMT] : [] : @azure/[email protected] : Verbose - No active account found, falling back to the host
ssoTokenHelper.ts:59 [Wed, 28 Aug 2024 10:15:29 GMT] : [] : @azure/[email protected] : Error - Cached tokens are not found for the account, proceeding with silent token request.
loggerCallback @ ssoTokenHelper.ts:59
executeCallback @ Logger.mjs:83
logMessage @ Logger.mjs:76
error @ Logger.mjs:90
acquireTokenFromCache @ NestedAppAuthController.mjs:198
await in acquireTokenFromCache
acquireTokenSilentInternal @ NestedAppAuthController.mjs:135
acquireTokenSilent @ NestedAppAuthController.mjs:277
acquireTokenSilent @ PublicClientApplication.mjs:91
_callee4$ @ ssoTokenHelper.ts:93
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_tryAcquireTokenSilent @ ssoTokenHelper.ts:98
tryAcquireTokenSilent @ ssoTokenHelper.ts:90
_callee3$ @ ssoTokenHelper.ts:81
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoTokenFromNAA @ ssoTokenHelper.ts:88
getSsoTokenFromNAA @ ssoTokenHelper.ts:38
_callee2$ @ ssoTokenHelper.ts:24
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoToken @ ssoTokenHelper.ts:36
getSsoToken @ ssoTokenHelper.ts:16
_callee$ @ apiHelper.ts:18
tryCatch @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
asyncGeneratorStep @ apiHelper.ts:2
_next @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
_sendApiRequest @ apiHelper.ts:90
sendApiRequest @ apiHelper.ts:9
_callee3$ @ logger.ts:168
tryCatch @ logger.ts:2
(anonymous) @ logger.ts:2
(anonymous) @ logger.ts:2
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
Promise.then
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
Promise.then
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
(anonymous) @ logger.ts:2
(anonymous) @ logger.ts:2
sendLogsToBackendAsync @ logger.ts:169
sendLogs @ justificationInput.tsx:123
(anonymous) @ useARIAButtonProps.js:39
(anonymous) @ useEventCallback.js:26
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291
executeDispatch @ react-dom.development.js:9041
processDispatchQueueItemsInOrder @ react-dom.development.js:9073
processDispatchQueue @ react-dom.development.js:9086
dispatchEventsForPlugins @ react-dom.development.js:9097
(anonymous) @ react-dom.development.js:9288
batchedUpdates$1 @ react-dom.development.js:26179
batchedUpdates @ react-dom.development.js:3991
dispatchEventForPluginEventSystem @ react-dom.development.js:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465
dispatchEvent @ react-dom.development.js:6457
dispatchDiscreteEvent @ react-dom.development.js:6430
Show 24 more frames
Show less
ssoTokenHelper.ts:62 [Wed, 28 Aug 2024 10:15:29 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenFailure
An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing.
An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing.
An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing.
An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing.
An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing.
An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing.
logger.ts:41 [Safetica]: Justification saved: 0,
aadcdn.msauth.net/shared/1.0/content/js/BssoInterrupt_Core_JQnUxWSvwsd9FrpspQmznw2.js:18 BSSO Telemetry: {"result":"Error","error":"NoExtension","type":"ChromeSsoTelemetry","data":{},"traces":["BrowserSSO Initialized","Creating ChromeBrowserCore provider","Sending message for method CreateProviderAsync","Received message for method CreateProviderAsync","Error: ChromeBrowserCore error NoExtension: Extension is not installed."]}
ssoTokenHelper.ts:62 [Wed, 28 Aug 2024 10:15:31 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenFailure
logger.ts:41 [Safetica]: Unable to acquire NAA token silently: InteractionRequiredAuthError: login_required: AADSTS50058: A silent sign-in request was sent but no user is signed in. The cookies used to represent the user's session were not sent in the request to Azure AD. This can happen if the user is using Internet Explorer or Edge, and the web app sending the silent sign-in request is in different IE security zone than the Azure AD endpoint (login.microsoftonline.com). Trace ID: 610938fa-0f9f-4054-bfec-375137adbe00 Correlation ID: 0191987b-b55f-7531-8ec0-5dab532c2dd8 Timestamp: 2024-08-28 10:15:31Z
customLogMethod @ logger.ts:41
error @ logger.ts:139
_callee4$ @ ssoTokenHelper.ts:96
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_throw @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_tryAcquireTokenSilent @ ssoTokenHelper.ts:98
tryAcquireTokenSilent @ ssoTokenHelper.ts:90
_callee3$ @ ssoTokenHelper.ts:81
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoTokenFromNAA @ ssoTokenHelper.ts:88
getSsoTokenFromNAA @ ssoTokenHelper.ts:38
_callee2$ @ ssoTokenHelper.ts:24
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoToken @ ssoTokenHelper.ts:36
getSsoToken @ ssoTokenHelper.ts:16
_callee$ @ apiHelper.ts:18
tryCatch @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
asyncGeneratorStep @ apiHelper.ts:2
_next @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
_sendApiRequest @ apiHelper.ts:90
sendApiRequest @ apiHelper.ts:9
_callee3$ @ logger.ts:168
tryCatch @ logger.ts:2
(anonymous) @ logger.ts:2
(anonymous) @ logger.ts:2
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
Promise.then
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
Promise.then
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
(anonymous) @ logger.ts:2
(anonymous) @ logger.ts:2
sendLogsToBackendAsync @ logger.ts:169
sendLogs @ justificationInput.tsx:123
(anonymous) @ useARIAButtonProps.js:39
(anonymous) @ useEventCallback.js:26
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291
executeDispatch @ react-dom.development.js:9041
processDispatchQueueItemsInOrder @ react-dom.development.js:9073
processDispatchQueue @ react-dom.development.js:9086
dispatchEventsForPlugins @ react-dom.development.js:9097
(anonymous) @ react-dom.development.js:9288
batchedUpdates$1 @ react-dom.development.js:26179
batchedUpdates @ react-dom.development.js:3991
dispatchEventForPluginEventSystem @ react-dom.development.js:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465
dispatchEvent @ react-dom.development.js:6457
dispatchDiscreteEvent @ react-dom.development.js:6430
Show 17 more frames
Show less
logger.ts:41 [Safetica]: Getting SSO from NAA interactively
ssoTokenHelper.ts:62 [Wed, 28 Aug 2024 10:15:31 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenStart
BssoInterrupt_Core_JQnUxWSvwsd9FrpspQmznw2.js:18 BSSO Telemetry: {"result":"Error","error":"NoExtension","type":"ChromeSsoTelemetry","data":{},"traces":["BrowserSSO Initialized","Creating ChromeBrowserCore provider","Sending message for method CreateProviderAsync","Received message for method CreateProviderAsync","Error: ChromeBrowserCore error NoExtension: Extension is not installed."]}
ssoTokenHelper.ts:62 [Wed, 28 Aug 2024 10:15:32 GMT] : [] : @azure/[email protected] : Info - Emitting event: msal:acquireTokenFailure
logger.ts:41 [Safetica]: Unable to acquire NAA token interactively: ServerError: user_cancelled: User cancelled the flow.
customLogMethod @ logger.ts:41
error @ logger.ts:139
_callee5$ @ ssoTokenHelper.ts:105
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_throw @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_tryAcquireTokenPopup @ ssoTokenHelper.ts:107
tryAcquireTokenPopup @ ssoTokenHelper.ts:100
_callee3$ @ ssoTokenHelper.ts:87
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoTokenFromNAA @ ssoTokenHelper.ts:88
getSsoTokenFromNAA @ ssoTokenHelper.ts:38
_callee2$ @ ssoTokenHelper.ts:24
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoToken @ ssoTokenHelper.ts:36
getSsoToken @ ssoTokenHelper.ts:16
_callee$ @ apiHelper.ts:18
tryCatch @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
asyncGeneratorStep @ apiHelper.ts:2
_next @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
_sendApiRequest @ apiHelper.ts:90
sendApiRequest @ apiHelper.ts:9
_callee3$ @ logger.ts:168
tryCatch @ logger.ts:2
(anonymous) @ logger.ts:2
(anonymous) @ logger.ts:2
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
Promise.then
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
Promise.then
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
(anonymous) @ logger.ts:2
(anonymous) @ logger.ts:2
sendLogsToBackendAsync @ logger.ts:169
sendLogs @ justificationInput.tsx:123
(anonymous) @ useARIAButtonProps.js:39
(anonymous) @ useEventCallback.js:26
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291
executeDispatch @ react-dom.development.js:9041
processDispatchQueueItemsInOrder @ react-dom.development.js:9073
processDispatchQueue @ react-dom.development.js:9086
dispatchEventsForPlugins @ react-dom.development.js:9097
(anonymous) @ react-dom.development.js:9288
batchedUpdates$1 @ react-dom.development.js:26179
batchedUpdates @ react-dom.development.js:3991
dispatchEventForPluginEventSystem @ react-dom.development.js:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465
dispatchEvent @ react-dom.development.js:6457
dispatchDiscreteEvent @ react-dom.development.js:6430
Show 17 more frames
Show less
BssoInterrupt_Core_JQnUxWSvwsd9FrpspQmznw2.js:18 BSSO Telemetry: {"result":"Error","error":"NoExtension","type":"ChromeSsoTelemetry","data":{},"traces":["BrowserSSO Initialized","Creating ChromeBrowserCore provider","Sending message for method CreateProviderAsync","Received message for method CreateProviderAsync","Error: ChromeBrowserCore error NoExtension: Extension is not installed."]}
logger.ts:41 [Safetica]: Unable to acquire Office runtime token: [object Object]
customLogMethod @ logger.ts:41
error @ logger.ts:139
_callee6$ @ ssoTokenHelper.ts:113
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_throw @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoTokenFromOfficeRuntime @ ssoTokenHelper.ts:116
getSsoTokenFromOfficeRuntime @ ssoTokenHelper.ts:109
_callee2$ @ ssoTokenHelper.ts:29
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
Promise.then
asyncGeneratorStep @ ssoTokenHelper.ts:2
_next @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
_getSsoToken @ ssoTokenHelper.ts:36
getSsoToken @ ssoTokenHelper.ts:16
_callee$ @ apiHelper.ts:18
tryCatch @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
asyncGeneratorStep @ apiHelper.ts:2
_next @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
(anonymous) @ apiHelper.ts:2
_sendApiRequest @ apiHelper.ts:90
sendApiRequest @ apiHelper.ts:9
_callee3$ @ logger.ts:168
tryCatch @ logger.ts:2
(anonymous) @ logger.ts:2
(anonymous) @ logger.ts:2
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
Promise.then
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
Promise.then
asyncGeneratorStep @ logger.ts:2
_next @ logger.ts:2
(anonymous) @ logger.ts:2
(anonymous) @ logger.ts:2
sendLogsToBackendAsync @ logger.ts:169
sendLogs @ justificationInput.tsx:123
(anonymous) @ useARIAButtonProps.js:39
(anonymous) @ useEventCallback.js:26
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291
executeDispatch @ react-dom.development.js:9041
processDispatchQueueItemsInOrder @ react-dom.development.js:9073
processDispatchQueue @ react-dom.development.js:9086
dispatchEventsForPlugins @ react-dom.development.js:9097
(anonymous) @ react-dom.development.js:9288
batchedUpdates$1 @ react-dom.development.js:26179
batchedUpdates @ react-dom.development.js:3991
dispatchEventForPluginEventSystem @ react-dom.development.js:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465
dispatchEvent @ react-dom.development.js:6457
dispatchDiscreteEvent @ react-dom.development.js:6430
Show 17 more frames
Show less
ssoTokenHelper.ts:32 Uncaught (in promise) AccessDeniedError: Do Office není nikdo přihlášený. Před odesláním se přihlaste.
at _callee2$ (ssoTokenHelper.ts:32:11)
at tryCatch (ssoTokenHelper.ts:2:1)
at Generator. (ssoTokenHelper.ts:2:1)
at Generator.throw (ssoTokenHelper.ts:2:1)
at asyncGeneratorStep (ssoTokenHelper.ts:2:1)
at _throw (ssoTokenHelper.ts:2:1)
_callee2$ @ ssoTokenHelper.ts:32
tryCatch @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
(anonymous) @ ssoTokenHelper.ts:2
asyncGeneratorStep @ ssoTokenHelper.ts:2
_throw @ ssoTokenHelper.ts:2
Promise.catch
sendLogs @ justificationInput.tsx:123
(anonymous) @ useARIAButtonProps.js:39
(anonymous) @ useEventCallback.js:26
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291
executeDispatch @ react-dom.development.js:9041
processDispatchQueueItemsInOrder @ react-dom.development.js:9073
processDispatchQueue @ react-dom.development.js:9086
dispatchEventsForPlugins @ react-dom.development.js:9097
(anonymous) @ react-dom.development.js:9288
batchedUpdates$1 @ react-dom.development.js:26179
batchedUpdates @ react-dom.development.js:3991
dispatchEventForPluginEventSystem @ react-dom.development.js:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465
dispatchEvent @ react-dom.development.js:6457
dispatchDiscreteEvent @ react-dom.development.js:6430
Show 17 more frames
Show less
owa.JquerySignalR.m.abc5d963.js:1
Network Trace (Preferrably Fiddler)
- Sent
- Pending
MSAL Configuration
{
auth: {
clientId: clientId,
authority: "https://login.microsoftonline.com/common"
}
}
Relevant Code Snippets
import env from "../../env";
import { TokenRetrievalFailedError } from "../definitions/errors";
import logger from "../logging/logger";
import { isNAASupported } from "./featureSetHelper";
import { createNestablePublicClientApplication, IPublicClientApplication, LogLevel } from "@azure/msal-browser";
const defaultSsoOptions: OfficeRuntime.AuthOptions = {
allowSignInPrompt: true,
allowConsentPrompt: false,
forMSGraphAccess: false,
};
export async function getSsoToken(): Promise<string> {
try {
var token = undefined;
const clientId = env.CLIENT_ID;
if(isNAASupported() && clientId)
token = await getSsoTokenFromNAA(clientId)
if (token)
return token;
return await getSsoTokenFromOfficeRuntime();
} catch (error: any) {
const msg = getErrorMessage(error);
throw new TokenRetrievalFailedError(msg)
}
}
async function getSsoTokenFromNAA(clientId: string): Promise<string | undefined> {
const tokenRequest = {
scopes: ["openid", "profile"],
};
logger.debug("Creating NPCA for SSO retrieval")
const npca = await createNestablePublicClientApplication({
auth: {
clientId: clientId,
authority: "https://login.microsoftonline.com/common"
}
});
logger.debug("Getting SSO from NAA silently")
var authResult = await tryAcquireTokenSilent(npca, tokenRequest)
if (authResult)
return authResult
logger.debug("Getting SSO from NAA interactively")
return await tryAcquireTokenPopup(npca, tokenRequest)
}
async function tryAcquireTokenSilent(pca: IPublicClientApplication, tokenRequest: { scopes: string[] }): Promise<string | undefined> {
try {
logger.debug("Getting SSO from NAA silently")
const userAccount = await pca.acquireTokenSilent(tokenRequest);
return userAccount.accessToken;
} catch (error) {
logger.error(`Unable to acquire NAA token silently: ${error}`);
}
}
async function tryAcquireTokenPopup(pca: IPublicClientApplication, tokenRequest: { scopes: string[] }): Promise<string | undefined> {
try {
const userAccount = await pca.acquireTokenPopup(tokenRequest);
return userAccount.accessToken;
} catch (error) {
logger.error(`Unable to acquire NAA token interactively: ${error}`);
}
}
async function getSsoTokenFromOfficeRuntime(): Promise<string> {
try {
return await OfficeRuntime.auth.getAccessToken(JSON.parse(JSON.stringify(defaultSsoOptions)));
} catch (error: any) {
logger.error(`Unable to acquire Office runtime token: ${error}`);
throw error;
}
}
Reproduction Steps
- Create plain outlook add-in project with onItemSend event handler and task pane.
- Create new app registration within your tenant with delegated permissions (["openid", "profile"]) and SPA redirect URL (can be brk-multihub://localhost:3000 if you run the add-in locally).
- replace clientId within our snippet with your clientId
- use the snippet to retrieve SSO token inside Safari or chrome browser (incognito window):
a. when sending mail (in event handler)
b. from task pane (on button click, for example)
Now you should get similar errors.
Expected Behavior
We expect this new way of authentication to work also within browser environment with third-party cookies restriction implemented. The add-in should get the token successfully.
Identity Provider
Entra ID (formerly Azure AD) / MSA
Browsers Affected (Select all that apply)
Chrome, Firefox, Safari
Regression
None
Source
External (Customer)