microsoft-authentication-library-for-js icon indicating copy to clipboard operation
microsoft-authentication-library-for-js copied to clipboard

MsalGuard - Support RBAC with CanActivateFn

Open dirthsj opened this issue 2 years ago • 9 comments

Core Library

MSAL.js v2 (@azure/msal-browser)

Wrapper Library

MSAL Angular (@azure/msal-angular)

Public or Confidential Client?

Public

Description

Starting with Angular 14.2, you can pass a CanActivateFn to the canActivate array. This function can contain inject calls and can be created dynamically at runtime very easily.

I have created a wrapper for MsalGuard which implements RBAC using this feature, but it would be nice if it was officially supported. Here is a sample of my implementation:

  static forRole(role: string): CanActivateFn {
    return (route, state) => {
      const msalGuard = inject(MsalGuard);
      const authGuardBase = new RoleAuthGuard(msalGuard, role);
      return authGuardBase.canActivate(route, state);
    }
  }

RoleAuthGuard handles waiting for MsalGuard to succeed, then acquires a token from Msal using acquireTokenSilent and verifies the idTokenClaims contain the specified role. This could be much more efficient if MsalGuard could verify the idTokenClaims internally.

Example Usage:

const routes: Routes = [
  {
    component: AdminComponent,
    path: 'admin',
    canActivate: [RoleAuthGuard.forRole('Administrator')],
  }
}

PS: Also of note, class and InjectionToken guards and resolvers, such as the current MsalGuard impelmentation, are scheduled for removal in Angular 17. CanActivateFn is the replacement. I would appreciate it if this feature was included when the necessary changes to support Angular 17 are made.

Source

External (Customer)

dirthsj avatar Mar 17 '23 18:03 dirthsj

@dirthsj @sameerag possibly related to #3406

derisen avatar Mar 17 '23 20:03 derisen

@dirthsj @sameerag possibly related to #3406

Exposing activateHelper etc. as proposed in this issue would not change the implementation of my wrapper (I would still prefer composition over inheritance).

However, it may be possible to provide a much more configurable MsalGuard using a similar approach to the one I requested; for example accepting callback functions for additional validation rather than just scopes.

Perhaps something like an MsalGuard.withTokenValidator((token) => ...)) would be better if the overall goal is flexibility.

dirthsj avatar Mar 17 '23 21:03 dirthsj

cc @EmLauber @jo-arroyo Can we track this as a feature request?

sameerag avatar Mar 18 '23 19:03 sameerag

@dirthsj This issue has been automatically marked as stale because it is marked as requiring author feedback but has not had any activity for 5 days. If your issue has been resolved please let us know by closing the issue. If your issue has not been resolved please leave a comment to keep this open. It will be closed automatically in 7 days if it remains stale.

ghost avatar Mar 26 '23 01:03 ghost

This comment exists to avoid the bot closing this issue. If any further information on my request is desired, I have not received that impression from the comments above.

dirthsj avatar Mar 26 '23 02:03 dirthsj

Assigning to myself as this is a feature enhancement we will take under consideration. At this time, we are still evaluating MSALGuard enhancements.

EmLauber avatar Mar 29 '23 22:03 EmLauber

@dirthsj I have a similar situation/need. However, rather than simply verifying the idTokenClaims to determine access, I need to grab a custom claim and make an API call to resolve roles & permissions for the successfully authenticated user.

Can you share or explain how your RoleAuthGuard implementation waits for the MsalGuard to complete?

miguellira avatar Aug 28 '23 12:08 miguellira

I'm away from work at the moment, so I can't get at my source code, but it's basically just calling msalGuard.canActivate, then using rxjs switchMap on the result, passing through the error cases and handling the success case with additional logic.

dirthsj avatar Aug 28 '23 15:08 dirthsj

Hello, I am also currently writing a wrapper for msal to add rbac. Luckily the current implementation still works with angular 17. Any news on the enhancement?

RaicuRobert avatar Nov 22 '23 22:11 RaicuRobert