Skip to content

When CDN and app live on different hosts, MSAL Guard calculates the destination url erroneously #7435

Open
@prewk

Description

@prewk

Core Library

MSAL.js (@azure/msal-browser)

Core Library Version

3.27.0

Wrapper Library

MSAL Angular (@azure/msal-angular)

Wrapper Library Version

3.1.0

Public or Confidential Client?

Public

Description

Scenario

  • Angular is built and its assets uploaded to https://cdn.example.com/my-app/1.2.3/
  • The application is served from an nginx web server at https://app.example.com/ (maybe it has the API there, or just a lot of important proxies etc)

The idiomatic way of doing this

  • Build the Angular app with --base-href="https://cdn.example.com/my-app/1.2.3/"
  • Provide https://app.example.com/ as APP_BASE_HREF (otherwise no routes will work)

This will set <base href="https://cdn.example.com/my-app/1.2.3/"> in the built index.html, not hardcode any base urls in the assets, and prefix all routes in the app with https://app.example.com/. Otherwise they'll try to use the base href and you'll end up on the CDN.

Error Message

What happens is that, a lot of times, the MSAL library will redirect away for auth, then back again to the CDN and not the app! Which of course explodes, because that's not where the app lives, it's served by a web server on https://app.example.com/.

I still haven't understood exactly when it happens and when it doesn't but the culprit seems to live here:

It calculates the baseUrl using the base element. Which Angular wants you to set to the CDN!

Here's some context where people got mad when Angular deprecated deployUrl (later reversed, but with gotchas) with suggestions about the idiomatic way of serving things: angular/angular-cli#23765

MSAL Logs

Not sure what logs are applicable here. I can barely capture anything before getting redirected away, I have to throw myself on the escape key :-)

Network Trace (Preferrably Fiddler)

  • Sent
  • Pending

MSAL Configuration

{
    auth: {
      clientId: 'super-secret-client-id',
      authority: 'super-secret-client-authority,
      redirectUri: 'https://app.example.com/',
      postLogoutRedirectUri: 'https://app.example.com/',
    },
    cache: {
      cacheLocation: BrowserCacheLocation.LocalStorage,
    }
}

Relevant Code Snippets

getDestinationUrl(path: string): string {
    this.authService.getLogger().verbose("Guard - getting destination url");
    // Absolute base url for the application (default to origin if base element not present)
    const baseElements = document.getElementsByTagName("base");
    const baseUrl = this.location.normalize(
      baseElements.length ? baseElements[0].href : window.location.origin
    );
    // ....

Reproduction Steps

  1. Configure your assets to live on a CDN referenced via <base href> as per Angular recommendations
  2. Serve the app from elsewhere
  3. Make your code path end up in getDestinationUrl by using the MsalGuard
  4. Trigger the guard - have it redirect you to Azure and back
  5. You end up on the CDN 💥

Expected Behavior

I expect to - when authenticating - jump back to where I started (the place the app is hosted from), not a completely different url (the referenced base href for the CDN).

Identity Provider

Entra ID (formerly Azure AD) / MSA

Browsers Affected (Select all that apply)

Chrome, Firefox, Edge, Safari

Regression

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs: Attention 👋Awaiting response from the MSAL.js teambug-unconfirmedA reported bug that needs to be investigated and confirmedmore-information-neededUse this label when you are waiting on information from the issue creatormsal-angularRelated to @azure/msal-angular packagemsal-browserRelated to msal-browser packagepublic-clientIssues regarding PublicClientApplicationsquestionCustomer is asking for a clarification, use case or information.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions