1

I am doing a POC on MSAL implementation on our Angular app.

Requirements: The user has to login once a day. When he visits more than once, he is to be taken directly to the app with no login interaction. The auth flow is only required for authentication and not authorization (no need for access tokens).

I have setup a test Azure AD account and have added the angular app to it. I have installed @azure/msal-angular and configured the same in app module as below:

export function MsalInstanceFactory(): IPublicClientApplication {
  return new PublicClientApplication({
    auth: {
      clientId: 'my clientId',
      redirectUri: '<domain>/azurePOC2/auth',
      authority: 'https://login.microsoftonline.com/common/',
      postLogoutRedirectUri: '<domain>//azurePOC2/logout'
    },
    cache: {
      cacheLocation: BrowserCacheLocation.LocalStorage,
      storeAuthStateInCookie: true
    },
    system: {
      loggerOptions: {
        loggerCallback: ()=>{}
      }
    }
  })
}

export function MsalGuardConfig(): MsalGuardConfiguration {
  return {
    interactionType: InteractionType.Redirect,
    loginFailedRoute: '<domain>/azurePOC2/error',
    authRequest: {
      scopes: ['openid']
    }
  }
}

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
    MsalModule
  ],
providers: [
    ...
    {
      provide: MSAL_INSTANCE,
      useFactory: MsalInstanceFactory
    },
    {
      provide: MSAL_GUARD_CONFIG,
      useFactory: MsalGuardConfig
    },
    MsalGuard,
    MsalService
  ],
  bootstrap: [AppComponent],
})
export class AppModule { }

I have added the MsalGuard to protect my route. The setup is working fine for the login and logout flow. The issue I am facing is with the auto logout at the end of the day.

The package stores the client information in the token in the local storage (is it safe to expose the information like that?). The local storage never expires or gets cleared unless I explicitly call MsalService.logout(). Since I am using a test account, the token expiry is 1H. When the actual development begins, the client will configure the expiry time in AD to suit their needs. But I need to figure out how to clear the local storage once the token expires. Can someone help?

Senthamizh
  • 53
  • 1
  • 10

2 Answers2

0

Are you using the latest version of MSAL because you don't need to clear your local storage manually and the library will handle that when the token is expired.

Rutha
  • 751
  • 3
  • 7
  • I am using the latest version of MSAL. For now, I found a workaround. I switched from local storage to session storage and modified the conditional access policy to disallow the issuing of new tokens after the expiry of the policy and force the user to interactive flow. The session storage gets cleared when the user closes the browser. When he comes back, MSAL tries to get a new token. If the access policy is alive, it will get new tokens, but if not, the user will be forced to go to interactive flow. – Senthamizh Aug 09 '21 at 10:14
  • 2
    But the core problem remains: Even when the token has expired, as long as it exists in browser storage, MSAL library doesn't consider it invalid. – Senthamizh Aug 09 '21 at 10:16
0

You'll have to listen for the ACQUIRE_TOKEN_FAILURE and clear the localstorage yourself. Get the MsalBroadcastService and the MsalService injected into your AppComponent or the service you use to handle authentication, then add the following code in the constructor:

import { MsalBroadcastService, MsalService } from '@azure/msal-angular';
...
constructor(
  private readonly msalService: MsalService,
  private readonly msalBroadcastService: MsalBroadcastService
) {
  this.msalBroadcastService.msalSubject$.pipe(filter((msg: EventMessage) => msg.eventType === EventType.ACQUIRE_TOKEN_FAILURE)).subscribe({
    next: () => {
      let msalInstance: PublicClientApplication = this.msalService.instance as PublicClientApplication;
      msalInstance['browserStorage'].clear();
    }
  });
}
Ε Г И І И О
  • 11,199
  • 1
  • 48
  • 63