Jan69
Jan69

Reputation: 1139

Angular web app with MSAL gives Cross-origin token redemption error

I am using MSAL with the angular web app. The application type is 'Web' in the Azure portal.

When I try to login using single sign-on I am getting below error. Once the user logins to the app we have to display the username of the current user.

AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type.

I don't want to change the application type to 'SPA'.

Angular version : 11

app.module.ts
--------------------
mport { MsalInterceptor, MSAL_INSTANCE, MSAL_GUARD_CONFIG, MsalGuardConfiguration, MsalBroadcastService, MsalGuard, MsalService, MSAL_INTERCEPTOR_CONFIG, MsalInterceptorConfiguration } from '@azure/msal-angular';

import { BrowserCacheLocation, InteractionType, IPublicClientApplication, LogLevel, PublicClientApplication } from '@azure/msal-browser';

const isIE = window.navigator.userAgent.indexOf("MSIE ") > -1 || window.navigator.userAgent.indexOf("Trident/") > -1;

export function loggerCallback(logLevel: LogLevel, message: string) {
    console.log(message);
}

export function MSALInstanceFactory(): IPublicClientApplication {
    return new PublicClientApplication({
        auth: {
            clientId: 'client id',
            redirectUri: window.location.origin,
            navigateToLoginRequestUrl: true,
            authority: 'https://login.microsoftonline.com/tenant_id/'

        },
        cache: {
            cacheLocation: BrowserCacheLocation.LocalStorage,
            storeAuthStateInCookie: false, // set to true for IE 11
        },

        system: {
            loggerOptions: {
                loggerCallback,
                logLevel: LogLevel.Info,
                piiLoggingEnabled: false
            },

        }


    });
}

export function MSALGuardConfigFactory(): MsalGuardConfiguration {
    return {
        interactionType: InteractionType.Redirect,
        authRequest: {
            scopes: []
        }
    };
}

export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
    return {
        interactionType: InteractionType.Redirect,
        protectedResourceMap: new Map<string, Array<string>>()
    }
}
---
---
providers: [
        {
            provide: HTTP_INTERCEPTORS,
            useClass: MsalInterceptor,
            multi: true
        },
        {
            provide: MSAL_INSTANCE,
            useFactory: MSALInstanceFactory
        },
        {
            provide: MSAL_GUARD_CONFIG,
            useFactory: MSALGuardConfigFactory
        },
        {
            provide: MSAL_INTERCEPTOR_CONFIG,
            useFactory: MSALInterceptorConfigFactory
        },
        MsalService,
        MsalGuard,
        MsalBroadcastService
    ],

component.ts
---------------



   private readonly onDestroy$ = new Subject<void>();
    constructor(
        @Inject(MSAL_GUARD_CONFIG) private msalGuardConfig: MsalGuardConfiguration,
        private authService: MsalService,
        private msalBroadcastService: MsalBroadcastService

    ) {
    }

   /*login() {
        if (this.msalGuardConfig.authRequest) {
            this.authService.loginPopup({ ...this.msalGuardConfig.authRequest } as RedirectRequest);
        } else {
            this.authService.loginPopup();
        }
    }*/

   login(){
       alert(this.msalGuardConfig.interactionType);
     //  if (this.msalGuardConfig.interactionType === InteractionType.Popup) {
           if (this.msalGuardConfig.authRequest){
               alert('inside if');
               this.authService.loginPopup({...this.msalGuardConfig.authRequest} as PopupRequest)
                   .subscribe((response: AuthenticationResult) => {
                       this.authService.instance.setActiveAccount(response.account);
                   });
           } else {
               alert('inside else');
               this.authService.loginPopup()
                   .subscribe((response: AuthenticationResult) => {
                       this.authService.instance.setActiveAccount(response.account);
                   });
           }
   //}
   }
   // public async login() {await this.authService.instance.loginRedirect();}

    logout() {
        this.authService.logoutPopup();
    }

    getUser(){

        alert(this.authService.instance.getActiveAccount());
    }
    ngOnDestroy() {
        this.onDestroy$.next();
    }

    ngOnInit(): void {
      //  const currentPath = this.location.path();
        // Dont perform nav if in iframe or popup, other than for front-channel logout
       // this.isIframe = BrowserUtils.isInIframe() && !window.opener && currentPath.indexOf("logout") < 0; // Remove this line to use Angular Universal

        this.msalBroadcastService.inProgress$
            .pipe(
                filter((status: InteractionStatus) => status === InteractionStatus.None),
                takeUntil(this.onDestroy$)
            )
            .subscribe(() => {
            
                this.checkAndSetActiveAccount();
            })
    }
 
    checkAndSetActiveAccount(){
      
   
        let activeAccount = this.authService.instance.getActiveAccount();

        if (!activeAccount && this.authService.instance.getAllAccounts().length > 0) {
            let accounts = this.authService.instance.getAllAccounts();
            this.authService.instance.setActiveAccount(accounts[0]);
        }
        alert('activeAccount');
alert(activeAccount);
        if(activeAccount) {
            alert(activeAccount.name);

        }
    }

Upvotes: 4

Views: 2204

Answers (1)

Charlie V
Charlie V

Reputation: 1040

You're trying to use a library that is setup for Single Page Applications. The authorisation flow is different for SPA and Web Apps. For SPA you have to use PCKE (or implicit), for WebApps you have to get the token in a different way.

What you can try is to look what you can adjust in your setting in the MSAL configuration in your Angular app based on the requirements from MS in this doc: https://github.com/Azure-Samples/ms-identity-javascript-nodejs-tutorial/blob/main/1-Authentication/1-sign-in/README.md

The other thing you can try is tweak the AD settings in your app registration. There you can also specify tokens, flows and redirect URLs.

Even if you get this to work now, in the future it might break because of changes that you cannot influence. I really recommend you to change the app type to SPA in Azure.

Upvotes: 1

Related Questions