AzureAD / microsoft-authentication-library-for-js

Microsoft Authentication Library (MSAL) for JS
http://aka.ms/aadv2
MIT License
3.64k stars 2.65k forks source link

SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON #6495

Closed rubimadi closed 1 year ago

rubimadi commented 1 year ago

Core Library

MSAL.js (@azure/msal-browser)

Core Library Version

2.5.0

Wrapper Library

MSAL Angular (@azure/msal-angular)

Wrapper Library Version

2.5.0

Public or Confidential Client?

Public

Description

The redirecting after a successful authentication does not work. I get the following error: SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON at JSON.parse (<anonymous>) at XMLHttpRequest.Je (https://n-246v007.zeitag.local/bridge4erp/main.7d6905408abe24c3.js:1:14913733) at T.invokeTask (https://n-246v007.zeitag.local/bridge4erp/polyfills.410f4001cc3bed13.js:1:7197) at Object.onInvokeTask (https://n-246v007.zeitag.local/bridge4erp/main.7d6905408abe24c3.js:1:15012114) at T.invokeTask (https://n-246v007.zeitag.local/bridge4erp/polyfills.410f4001cc3bed13.js:1:7118) at I.runTask (https://n-246v007.zeitag.local/bridge4erp/polyfills.410f4001cc3bed13.js:1:2592) at m.invokeTask [as invoke] (https://n-246v007.zeitag.local/bridge4erp/polyfills.410f4001cc3bed13.js:1:8248) at S (https://n-246v007.zeitag.local/bridge4erp/polyfills.410f4001cc3bed13.js:1:20147) at XMLHttpRequest.D (https://n-246v007.zeitag.local/bridge4erp/polyfills.410f4001cc3bed13.js:1:20471)

The error message itself is understandable. Parsing index.html as a JSON object result in this error. What I don't undestand, is why this parsing is happining in the first place. I assume its caused by MSAL, because it happens immediately after the redirecting.

I added the URL "https://n-246v007.zeitag.local/bridge4erp/" to the SPA Redirect URIs of the registered application

MSAL Configuration

export function MSALInstanceFactory(configLoader: AzureConfigLoaderService): IPublicClientApplication {
  const auth = configLoader.getConfig();
  return new PublicClientApplication({
    auth: auth,
    cache: {
      cacheLocation: BrowserCacheLocation.LocalStorage,
      storeAuthStateInCookie: false
    },
    system: {
      loggerOptions: {
        loggerCallback: (logLevel: LogLevel, message: string): void => {
          switch (logLevel) {
            case LogLevel.Error:
                console.error(message);
                return;
            case LogLevel.Info:
                console.info(message);
                return;
            case LogLevel.Verbose:
                console.debug(message);
                return;
            case LogLevel.Warning:
                console.warn(message);
                return;
        }
        },
        logLevel: LogLevel.Verbose,
        piiLoggingEnabled: false
      }
    }
  });
}

@Injectable({ providedIn: 'root' })
export class AzureConfigLoaderService {

  constructor(@Inject(AZURE_AUTH_CONFIG) private authConfig,) {
  }

  getConfig() {
    return {
      clientId: this.authConfig?.clientId.trim(),
      authority: this.authConfig?.authority.trim(),
      redirectUri: window.location.href
    };
  }
}

@NgModule({
  imports: [MsalModule],
  providers: [
    AzureConfigLoaderService,
    {
      provide: APP_INITIALIZER,
      useFactory: (authService: MsalService) => {
        return (): void => {
          authService.getLogger().verbose('MsalRedirectService activated');
          authService
            .initialize()
            .pipe(concatMap(() => authService.handleRedirectObservable()))
            .subscribe();
        };
      },
      deps: [MsalService],
      multi: true
    },
    {
      provide: MSAL_INSTANCE,
      useFactory: MSALInstanceFactory,
      deps: [AzureConfigLoaderService]
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: MsalInterceptor,
      multi: true
    },
    {
      provide: MSAL_GUARD_CONFIG,
      useFactory: (): MsalGuardConfiguration => {
        return {
          interactionType: InteractionType.Redirect,
          authRequest: {
            scopes: ['user.read']
          }
        };
      }
    },
    {
      provide: MSAL_INTERCEPTOR_CONFIG,
      useFactory: (): MsalInterceptorConfiguration => {
        const protectedResourceMap = new Map<string, Array<string>>();
        protectedResourceMap.set('https://graph.microsoft.com/v1.0/me', ['user.read']);

        return {
          interactionType: InteractionType.Redirect,
          protectedResourceMap
        };
      }
    },
    MsalService,
    MsalGuard,
    MsalBroadcastService
  ]
})
export class AzureModule { }

Relevant Code Snippets

No response

Identity Provider

None

Source

External (Customer)

jo-arroyo commented 1 year ago

@rubimadi Please see our doc on using redirects here as well as our samples for how to implement redirect in an Angular app. Please also upgrade to the latest version of MSAL Angular.

rubimadi commented 1 year ago

I'm using the approach with handleRedirectObservable to handle the redirecting. I can't see anything wrong with my code.

this.msal .handleRedirectObservable() .pipe(take(1), takeUntil(this.destroyed$)) .subscribe(_ => { if (!_) { return; } this.exchangeToken(_.accessToken); });

I would be helpful, if you could point me in a specific direction to look at in order to solve the problem.

jo-arroyo commented 1 year ago

@rubimadi You should not be trying to use handleRedirectObservable when providing the MsalService. Please see this sample app for the correct way to provide MsalService and use handleRedirectObservable.

Closing as guidance has been provided via samples and documentation.

rubimadi commented 1 year ago

These are V3 samples, which aren't compatibel with Angular 14, which I'm using at the moment and I can't update to Angular 15 or higher right now.

rubimadi commented 1 year ago

It turns out that a third-party library uses window.location.href to load some json files on the loading of the web application during the redirecting. And because MSAL attaches the token as a parameter to the redirected URL, the json files are not found.

mfandre commented 2 weeks ago

It turns out that a third-party library uses window.location.href to load some json files on the loading of the web application during the redirecting. And because MSAL attaches the token as a parameter to the redirected URL, the json files are not found.

Did fix? Could you tell how do you fix it? Im apparently have the same problem...