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

PR #7137 introduced a breaking change into path-scopes matching

Open PalSzoboszlay opened this issue 1 year ago • 6 comments

Core Library

MSAL.js (@azure/msal-browser)

Core Library Version

3.17.0

Wrapper Library

MSAL Angular (@azure/msal-angular)

Wrapper Library Version

3.0.20

Public or Confidential Client?

Public

Description

Bug source: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/362442e1681867ca90ddf860d82e115436b8b1a6/lib/msal-angular/src/msal.interceptor.ts#L286

checkUrlComponents's new implementation has a way stricter path matching than previously, so Given a protected resource map of "myApi.companyName" - scopes and a GET request going out to "https://myApi.companyName.com/route" (using MsalInterceptor) while running the UI locally (http://localhost:4200)

The method already returns false when checking the protocol because it tries to match "http" to "https", but it would also fail the next host match ("localhost:4200" vs "myApi.companyName.com").

In matchResourcesToEndpoint, the absolute key from "myApi.companyName" turns into "http://localhost:4200/myApi.companyName", with the keyComponents.pathname being "/myApi.companyName", and this would be compared to the absoluteEndpoint's pathname "/route" which wouldn't match either.

Previously it had no issue matching "myApi.companyName" to "https://myApi.companyName.com/route" to get a token, but now it logs "Interceptor - no scopes for endpoint" with verbose logging

(The issue would be the same if it wasn't running locally, as the deployed UI's host is not "myApi.companyName.com")

Error Message

No response

MSAL Logs

(app) MSAL Logging: [Mon, 24 Jun 2024 10:59:53 GMT] : [eef18fce-9344-4da7-ad45-8436b465b901] : @azure/[email protected] : Verbose - MSAL Interceptor activated auth.module.ts:41 (app) MSAL Logging: [Mon, 24 Jun 2024 10:59:53 GMT] : [eef18fce-9344-4da7-ad45-8436b465b901] : @azure/[email protected] : Verbose - Interceptor - getting scopes for endpoint auth.module.ts:41 (app) MSAL Logging: [Mon, 24 Jun 2024 10:59:53 GMT] : [eef18fce-9344-4da7-ad45-8436b465b901] : @azure/[email protected] : Verbose - Interceptor - no scopes for endpoint

Network Trace (Preferrably Fiddler)

  • [ ] Sent
  • [ ] Pending

MSAL Configuration

{
    auth: {
      clientId: '***',
      authority: '***',
      redirectUri: window.location.origin,
      postLogoutRedirectUri: window.location.origin,
      navigateToLoginRequestUrl: true,
    },
    cache: {
      cacheLocation: 'localStorage',
      storeAuthStateInCookie: isIE, // set to true for IE 11
    },
    system: {
      loggerOptions: {
        loggerCallback: (logLevel, message, piiEnabled) => {
          console.log('(app) MSAL Logging: ', message);
        },
        logLevel: LogLevel.Verbose,
        correlationId: uuid(),
        piiLoggingEnabled: false
      }
    }
  });
}

Relevant Code Snippets

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { MsalModule, MsalService, MsalInterceptor, MsalInterceptorConfiguration, MSAL_INSTANCE, MSAL_INTERCEPTOR_CONFIG, MSAL_GUARD_CONFIG, MsalGuardConfiguration, MsalGuard } from '@azure/msal-angular';

function MSALInterceptorConfigFactory(configService: ConfigurationService): MsalInterceptorConfiguration {
  const protectedResourceMap = new Map<string, Array<string>>();
  protectedResourceMap.set("myApi.companyName", ["scope1"]);

  return {
    interactionType: InteractionType.Redirect,
    protectedResourceMap,
  }
}

function MSALInstanceFactory(configService: ConfigurationService): IPublicClientApplication {
  return new PublicClientApplication(...)}


@NgModule({
  imports: [
    CommonModule,
    MsalModule,
  ],
  declarations: [],
  providers: [
    MsalInterceptor,
    MsalService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: MsalInterceptor,
      multi: true
    },
    {
      provide: MSAL_INSTANCE,
      useFactory: MSALInstanceFactory
    },
    {
      provide: MSAL_INTERCEPTOR_CONFIG,
      useFactory: MSALInterceptorConfigFactory
    }
  ],
})
export class AuthModule { }

Reproduction Steps

  1. Set up an Angular app with an interceptor. Try to use a similar approach as described above when setting up protectedResourceMap. (use partial urls)
  2. Send a request to the API

Expected Behavior

The Bearer token should be added to the request instead of logging "no scopes for endpoint". Alternatively please update your documentation to explain how the protectedResourceMap should be set up in the future that doesn't require something like the following hack: https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/7111#issuecomment-2173690669

Identity Provider

Entra ID (formerly Azure AD) / MSA

Browsers Affected (Select all that apply)

Chrome, Firefox, Edge

Regression

@azure/msal-browser@^3.15.0 @azure/[email protected]

Source

Internal (Microsoft)

PalSzoboszlay avatar Jun 24 '24 11:06 PalSzoboszlay

@PalSzoboszlay Thanks for documenting this. I will be investigating for either a bugfix or a documentation update, and will post updates here. Thanks

jo-arroyo avatar Jun 25 '24 14:06 jo-arroyo

Seems similar to what I encountered and posted in discussion #7163

danvod avatar Jun 27 '24 12:06 danvod

I have the same issue with localhost!

MurhafSousli avatar Jun 28 '24 23:06 MurhafSousli

Adding a comment to keep this issue open

PalSzoboszlay avatar Jul 04 '24 14:07 PalSzoboszlay

@jo-arroyo This issue was closed automatically, can I expect an update for it anyways?

PalSzoboszlay avatar Jul 12 '24 08:07 PalSzoboszlay

Reopening issue. As the change made to the MSAL Interceptor was to address a bug in the way MSAL Interceptor handled relative paths (as you linked above), I will update the documentation to reflect this. Apologies for the confusion. I will keep this issue open and update it when that change is made.

jo-arroyo avatar Jul 12 '24 22:07 jo-arroyo