microsoft-authentication-library-for-js: Angular: MSAL Guard doesn't implement CanLoad, CanActivateChild, only CanActivate

I’m submitting a…


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Other... Please describe:

Browser:

  • Chrome version XX
  • Firefox version XX
  • IE version XX
  • Edge version XX
  • Safari version XX
  • All

Library version


Library version: 0.1.4

Current behavior

The following modules are imported only once in app.module.ts: MsalModule and HttpClientModule. The MsalInterceptor is mentioned in the providers for app.module.ts and only there as well.

Requests made to our ASP.NET Core 3 Web API from within the AppModule correctly attach the tokens for authentication via the MsalInterceptor. However, all other requests to our API via HttpClient in Feature modules are not getting intercepted for token to be attached to the request.

Expected behavior

The interceptor should work for Feature modules as well.

Minimal reproduction of the problem with instructions

  • Use HttpClient in Feature module
  • Use HttpClient in AppModule (or module that has the MsalInterceptor as a provider)
  • Observe only requests coming from module that uses MsalInterceptor as provider intercept the request to attach the token, whereas requests coming from Feature modules do NOT get intercepted.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 1
  • Comments: 32 (7 by maintainers)

Most upvoted comments

I have solved the issue! And I have a suggestion related to the MsalGuard. First,

Solution

The MsalService forces the assumption that a route that appears in the Angular Router’s events observable that does not use canActivate will be considered an unprotectedResource. I had forgotten to put canActivate on my parent route in my feature module’s router module (but I also wonder if I should need it since I’m not rendering a component for that route). My routing module looked like:


const routes: Routes = [
    {
        path: 'questionnaires',
        // canActivate: [MsalGuard], // <-- fixes the issue
        // canActivateChild: [MsalGuard], // <-- throws an error!
        children: [
            {
                path: 'all',
                component: QuestionnairesComponent,
                canActivate: [MsalGuard],
            },
            {
                path: 'new',
                component: NewQuestionnaireComponent,
                canActivate: [MsalGuard],
            },
            {
                path: '',
                pathMatch: 'full',
                redirectTo: 'all',
            },
        ],
    },
];

@NgModule({
    imports: [RouterModule.forChild(routes)],
    exports: [RouterModule],
})
export class QuestionnairesRoutingModule {}

Suggestion

Could we make the MsalGuard implement more than just CanActivate? For instance, CanActivateChild and CanLoad would be really useful ones for me as well as other (I’m assuming).

@jakehockey10 Thanks for the update! Yeah, that seems like a reasonable request. I’ll create a new ticket to track that work, which I’ll add to the next Angular release.

CanActivateChild and CanLoad have been added to MSAL Angular v2, and will be available in the next release. Thanks for all your feedback!

Found an additional bug… Some of my routes are setup as follows:

const routes: Routes = [
	{
		path: 'meetings',
		children: [
			{ path: '', component: MeetingsComponent, pathMatch: 'full', canActivate: [MsalGuard] },
			{ path: 'actions/:id', component: MeetingActionsComponent, canActivate: [MsalGuard] },
			{ path: 'edit/:id', component: MeetingEditComponent, canActivate: [MsalGuard] }
		]
	},
	{
		path: 'rooms',
		children: [
			{ path: '', component: RoomsComponent, pathMatch: 'full', canActivate: [MsalGuard] }
		]
	}
]

Since MsalGuard doesn’t implement CanActivateChildren, I have to protect them manually… By doing this, the ‘parent routes’: “meeting” & “rooms” are left unprotected, except they aren’t if you look at the first child route.

The problem is that MsalGuard adds these routes to the unproctectedresources map.
And my backend API defines the following routes: “…/api/meetings” and “…/api/rooms”.

You can probably see where this is headed: When I make a call to these api routes, the method
private isUnprotectedResource(url: string): boolean
in MsalService.ts marks these as unprotected, thus doesn’t add the Auth headers

I haven’t tested whether this problem happens in production where the backend is located on another url, but now it’s impossible to debug locally with this setup:
Angular host: ‘localhost:4200’ ASP Backend host: ‘localhost:5001’

I hope what I’ve written is readable/understandable 😅

A simple workaround of course is to ALSO add the guard to the parent routes, but I hope this general issue is quickly fixed!

@jakehockey10 I’d love to hear any feedback you have, feel free to email (on my profile), thanks!

@eeskildsen I’ve been having a lot of trouble getting this library to work with any modularization. As soon as I start grouping functionality into feature modules, everything just falls apart. I don’t understand, at all, how to keep my project organized and have this library continue to facilitate my authorization needs across multiple modules. Sounds like you’ve had some success though

@jasonnutter just wanted to follow up with you. We wanted to take a look and see how things might be changing for us when upgrading to the new version once it is released and tried it the alpha yesterday. It did not fix the msalinterceptor not working in the feature module but it was good to get a preview for some of the changes will need to make during the upgrade process. I’ll attempt to investigate the interceptor more on our end and keep you posted of anything we learn