microsoft-authentication-library-for-js
microsoft-authentication-library-for-js copied to clipboard
Observable fro msalBroadcastService doesn't send all InteractionStatus or Event
Core Library
MSAL.js v2 (@azure/msal-browser)
Core Library Version
2.18.0
Wrapper Library
MSAL Angular (@azure/msal-angular)
Wrapper Library Version
2.0.4
Description
Since msal-angular 2.0.3, Observables from msalBroadcastService
doesn't send all data:
-
inProgress$
: missing someInteractionStatus
such asnone
. I receive onlystartup
-
msalSubject$
: missing someEventMessage
such ashandleRedirectStart
. I receive some other likehandleRedirectEnd
Error Message
No response
Msal Logs
3 '[Wed, 20 Oct 2021 16:11:21 GMT] : @azure/[email protected] : Verbose - MsalRedirectComponent activated' msalInstance.factory.ts:8
3 '[Wed, 20 Oct 2021 16:11:21 GMT] : @azure/[email protected] : Verbose - handleRedirectPromise called' msalInstance.factory.ts:8
3 '[Wed, 20 Oct 2021 16:11:21 GMT] : @azure/[email protected] : Verbose - getAllAccounts called' msalInstance.factory.ts:8
2 '[Wed, 20 Oct 2021 16:11:21 GMT] : @azure/[email protected] : Info - Emitting event: msal:handleRedirectStart' msalInstance.factory.ts:8
3 '[Wed, 20 Oct 2021 16:11:21 GMT] : @azure/[email protected] : Verbose - handleRedirectPromise has been called for the first time, storing the promise' msalInstance.factory.ts:8
3 '[Wed, 20 Oct 2021 16:11:21 GMT] : [5fc57d40-0f7c-41a6-bf5c-b1cca863e9a4] : [email protected] : Verbose - initializeServerTelemetryManager called' msalInstance.factory.ts:8
2 '[Wed, 20 Oct 2021 16:11:21 GMT] : [5fc57d40-0f7c-41a6-bf5c-b1cca863e9a4] : [email protected] : Info - handleRedirectPromise called but there is no interaction in progress, returning null.' core.js:28039
Angular is running in development mode. Call enableProdMode() to enable production mode. msalInstance.factory.ts:8
3 '[Wed, 20 Oct 2021 16:11:21 GMT] : @azure/[email protected] : Verbose - Event callback registered with id: fd4aeb5a-9e1b-45ea-b685-3f9c66bbfbf6' msalInstance.factory.ts:8
3 '[Wed, 20 Oct 2021 16:11:21 GMT] : @azure/[email protected] : Verbose - getAllAccounts called' auth.service.ts:31
MSAL Interaction Status: startup msalInstance.factory.ts:8
2 '[Wed, 20 Oct 2021 16:11:21 GMT] : @azure/[email protected] : Info - Emitting event: msal:handleRedirectEnd' msalInstance.factory.ts:8
3 '[Wed, 20 Oct 2021 16:11:21 GMT] : @azure/[email protected] : Verbose - Emitting event to callback fd4aeb5a-9e1b-45ea-b685-3f9c66bbfbf6: msal:handleRedirectEnd'
auth.service.ts:45
MSAL Event Type: msal:handleRedirectEnd index.js:52
[WDS] Live Reloading enabled.
MSAL Configuration
export function MSALInstanceFactory(): IPublicClientApplication {
return new PublicClientApplication({
auth: {
clientId: environment.aad.clientId,
authority: 'https://login.microsoftonline.com/' + environment.aad.tenantId,
redirectUri: environment.aad.redirectUri,
postLogoutRedirectUri: '/',
navigateToLoginRequestUrl: true
},
cache: {
cacheLocation: 'sessionStorage',
storeAuthStateInCookie: false
},
system: {
loggerOptions: {
loggerCallback,
logLevel: LogLevel.Verbose,
piiLoggingEnabled: false
}
}
});
}
Relevant Code Snippets
// inProgress Observble
this.msalBroadcastService.inProgress$.subscribe({
next: (status: InteractionStatus) => {
if (environment.debug.msal) {
console.log(`MSAL Interaction Status: ${status}`);
}
}
});
// msalSubject observable
this.msalBroadcastService.msalSubject$.subscribe({
next: (event: EventMessage) => {
if (environment.debug.msal) {
console.log(`MSAL Event Type: ${event.eventType}`);
}
}
});
Reproduction Steps
- Clone https://github.com/0xdbe-example/angular-msal-azure-ad
- Configure Azure AD and MSAL (in environment file)
- Run with
ng serve
(needs mkcert for HTTPS) - Open your browser, authentication should works
- Update MSAL and restart
- Open your browser, authentication doesn't work anymore.
Expected Behavior
-
inProgress$
: must send allInteractionStatus
includingnone
-
msalSubject$
: must send allEventMessage
includinghandleRedirectStart
Identity Provider
Azure AD / MSA
Browsers Affected (Select all that apply)
Chrome
Regression
@azure/msal-angular 2.0.1 with @azure/msal-browser 2.16.1
Source
External (Customer)
@0xdbe Thanks for the information. Did you try debugging MSAL Angular or MSAL Browser to see what is happening? Are the events being emitted from MSAL Browser but dropped by MSAL Angular, or not getting emitted by MSAL Browser at all?
@jasonnutter:
Here, verbose log with @azure/msal-angular v2.0.4:
Navigated to https://localhost:4200/
core.js:28039 Angular is running in development mode. Call enableProdMode() to enable production mode. msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:12:47 GMT] : @azure/[email protected] : Verbose - MsalRedirectComponent activated' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:12:47 GMT] : @azure/[email protected] : Verbose - handleRedirectPromise called' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:12:47 GMT] : @azure/[email protected] : Verbose - getAllAccounts called' msalInstance.factory.ts:9
2 '[Tue, 26 Oct 2021 14:12:47 GMT] : @azure/[email protected] : Info - Emitting event: msal:handleRedirectStart' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:12:47 GMT] : @azure/[email protected] : Verbose - handleRedirectPromise has been called for the first time, storing the promise' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:12:47 GMT] : [d2ab448f-f2c7-412d-b067-ebd3a03d458b] : [email protected] : Verbose - initializeServerTelemetryManager called' msalInstance.factory.ts:9
2 '[Tue, 26 Oct 2021 14:12:47 GMT] : [d2ab448f-f2c7-412d-b067-ebd3a03d458b] : [email protected] : Info - handleRedirectPromise called but there is no interaction in progress, returning null.' core.js:28039
Angular is running in development mode. Call enableProdMode() to enable production mode. msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:12:47 GMT] : @azure/[email protected] : Verbose - Event callback registered with id: b9e13b68-a36a-4fad-8fd9-acca84c176ae' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:12:47 GMT] : @azure/[email protected] : Verbose - getAllAccounts called' auth.service.ts:31
MSAL Interaction Status: startup msalInstance.factory.ts:9
2 '[Tue, 26 Oct 2021 14:12:47 GMT] : @azure/[email protected] : Info - Emitting event: msal:handleRedirectEnd' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:12:47 GMT] : @azure/[email protected] : Verbose - Emitting event to callback b9e13b68-a36a-4fad-8fd9-acca84c176ae: msal:handleRedirectEnd' auth.service.ts:45
MSAL Event Type: msal:handleRedirectEnd index.js:52
[WDS] Live Reloading enabled.
And now log with @azure/msal-angular v2.0.1 and msal-browser v2.18.0:
Navigated to https://localhost:4200/
core.js:28047 Angular is running in development mode. Call enableProdMode() to enable production mode. msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:23:19 GMT] : @azure/[email protected] : Verbose - MsalRedirectComponent activated' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:23:19 GMT] : @azure/[email protected] : Verbose - handleRedirectPromise called' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:23:19 GMT] : @azure/[email protected] : Verbose - getAllAccounts called' msalInstance.factory.ts:9
2 '[Tue, 26 Oct 2021 14:23:19 GMT] : @azure/[email protected] : Info - Emitting event: msal:handleRedirectStart' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:23:19 GMT] : @azure/[email protected] : Verbose - handleRedirectPromise has been called for the first time, storing the promise' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:23:19 GMT] : [ddde7be9-eca5-4e56-8af3-03d3ce16255a] : [email protected] : Verbose - initializeServerTelemetryManager called' msalInstance.factory.ts:9
2 '[Tue, 26 Oct 2021 14:23:19 GMT] : [ddde7be9-eca5-4e56-8af3-03d3ce16255a] : [email protected] : Info - handleRedirectPromise called but there is no interaction in progress, returning null.' core.js:28047
Angular is running in development mode. Call enableProdMode() to enable production mode. msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:23:19 GMT] : @azure/[email protected] : Verbose - Event callback registered with id: 781dd2ff-9b02-4ff5-83c5-e0f235a3612d' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:23:19 GMT] : @azure/[email protected] : Verbose - getAllAccounts called' auth.service.ts:31
MSAL Interaction Status: startup msalInstance.factory.ts:9
2 '[Tue, 26 Oct 2021 14:23:19 GMT] : @azure/[email protected] : Info - Emitting event: msal:handleRedirectEnd' msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:23:19 GMT] : @azure/[email protected] : Verbose - Emitting event to callback 781dd2ff-9b02-4ff5-83c5-e0f235a3612d: msal:handleRedirectEnd' auth.service.ts:45
MSAL Event Type: msal:handleRedirectEnd msalInstance.factory.ts:9
3 '[Tue, 26 Oct 2021 14:23:19 GMT] : @azure/[email protected] : Verbose - BroadcastService - msal:handleRedirectEnd results in setting inProgress to none' auth.service.ts:31
MSAL Interaction Status: none auth.service.ts:129
BehaviorSubject {_isScalar: false, observers: Array(1), closed: false, isStopped: false, hasError: false, …}
index.js:52 [WDS] Live Reloading enabled.
As you can see, with MSAL angular v2.01, I receive events from BroadcastService.
To understand what happens in my prototype, I decide to test the angular official sample app with @azure/msal-angular v2.0.4 => I receive all events from BroadcastService
!
The difference between my prototype and the sample app:
- In my prototype, the subscription to BroadcastService observable is in auth.service.ts (a service, not a component).
- In your angular example, the subscription to BroadcastService observable is in app root component.
So, I found a workaround: add msalBroadcastService
in app component constructor !
export class AppComponent {
constructor(
private msalBroadcastService: MsalBroadcastService
) {}
It works but I don't understand why it is needed to inject MsalBroadcastService in the root component.
The MsalBroadcastService
is already in providers list (in app root module).
I update my project to use @azure/[email protected]: https://github.com/0xdbe-example/angular-msal-azure-ad/commit/a692420ec4fc8cea574189b7b50cf1d94d481ba3
It works but MsalBroadcastService
is injected in app component constructor (without subscription). I don't know why is needed.
@0xdbe Interesting, thanks for the update. I wonder if this is timing-related (i.e. the required event listener isn't registered in time to capture certain events from MSAL)?
How can I check that?
You can try debugging the emitEvent
function and seeing if event listeners are registered when teh events you are missing are emitted: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/310c2b33484650689e949e72d56e778af76265d9/lib/msal-browser/src/event/EventHandler.ts#L104
Indeed, it could be timing-related.
Execution Flow
Step 1
MsalRedirectComponent
is firstly loaded. It seems normal since this component is defined in module bootstrap.
This component emits a new event: msal:handleRedirectStart
. But MsalBroadcastService
can't take into consideration this event because this service is yet loaded
Step 2
MsalBroadcastService
starts and runs the following actions:
- Init
inProgress$
observable toInteractionStatus.Startup
- Register event callback
Step 3
MsalRedirectComponent
sends new event msal:handleRedirectEnd
.
MsalBroadcastService
receives this event and tries to define the status:
const status = EventMessageUtils.getInteractionStatusFromEvent(EventMessage, currentStatus);
where:
- EventMessage.eventType = handleRedirectEnd
- currentStatus = startup
getInteractionStatusFromEvent
returns null
because:
case EventType.HANDLE_REDIRECT_END:
if (currentStatus && currentStatus !== InteractionStatus.HandleRedirect) {
// Prevent this event from clearing any status other than handleRedirect
break;
}
return InteractionStatus.None;
So, status will never set to InteractionStatus.None
Origin
Previously, getInteractionStatusFromEvent
takes only EventMessage
to define status
since this commit https://github.com/AzureAD/microsoft-authentication-library-for-js/commit/2d8898a9e87b5844d6b4b7ed7c9ebfdaf6bc7491# getInteractionStatusFromEvent
takes EventMessage
AND currentStatus
.
Workaround
Start MsalBroadcastService
before MsalRedirectComponent
, such as in appComponent
.
Fix
- Inject
MsalBroadcastService
inMsalRedirectComponent
? - update
getInteractionStatusFromEvent
?
This issue requires attention from the MSAL.js team and has not seen activity in 5 days. @jasonnutter please follow up.
@0xdbe Thank you for the details. We'll add this to our backlog as a potential enhancement.
@0xdbe Curious if the changes made in #4998 help here?
Any updates?
Still reproducing with Angular v14 and "@azure/msal-angular": "^2.5.5"
, "@azure/msal-browser": "^2.35.0"
.
If I don't inject private msalBroadcastService: MsalBroadcastService
in my auth.service.ts
, I'm unable to login/logout.
This issue still exists. I'm getting only 'Startup' interaction status and couldn't get status as 'None'. Any permanent fix for this issue would be really helpful.
I used APP_INITIALIZER for the redirect handling. It works only when I include MsalBroadcastService as a dependency:
{
provide: APP_INITIALIZER,
useFactory: (authService: MsalService) => () => authService.handleRedirectObservable(),
deps: [MsalService, MsalBroadcastService],
multi: true
},
Otherwise I get startup
when the Interceptor tries to refresh the token.
Finally found this issue, and while I am very happy for the workaround, it is also very frustrating that they needed to be imported in a specific order.
For us, it caused redirect logins not to work as fallback in the angular intercetpr (because state was never emitted properly).
I used APP_INITIALIZER for the redirect handling. It works only when I include MsalBroadcastService as a dependency:
{ provide: APP_INITIALIZER, useFactory: (authService: MsalService) => () => authService.handleRedirectObservable(), deps: [MsalService, MsalBroadcastService], multi: true },
Otherwise I get
startup
when the Interceptor tries to refresh the token.
This fixed it for me. The problem originally started after migrating to use standalone components.
Any updates on this?