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

PKCE Not Created Error After Upgrading to @azure/msal-angular@2.0.0-alpha.0 #2595

Closed Dudleytmc closed 3 years ago

Dudleytmc commented 3 years ago

Library

Framework

Angular 10.1.2

Description

I started receiving the following error once I cleared my browser cache after upgrading from @azure/msal-angular@1.1.1 to @azure/msal-angular@2.0.0-alpha.0. This seems to only occur after clearing my cache but now my application will no longer load.

Error Message

image

Security

Regression

MSAL Configuration

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

export function MSALInstanceFactory(): IPublicClientApplication {
  return new PublicClientApplication({
    auth: {
      clientId: 'xxxxxxxxxxxxxxxxx',
      redirectUri: environment.msal.redirectURL,
      postLogoutRedirectUri: environment.msal.redirectURL,
    },
    cache: {
      cacheLocation: BrowserCacheLocation.LocalStorage,
      storeAuthStateInCookie: isIE, // set to true for IE 11
    },
  });
}

export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
  const protectedResourceMap = new Map<string, Array<string>>();
  protectedResourceMap.set('http://localhost:4200', ['xxxxxxxxxxxxxx']);

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

export function MSALGuardConfigFactory(): MsalGuardConfiguration {
  return { interactionType: InteractionType.Redirect };
}

@NgModule({
.
.
.
  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
    }],
  bootstrap: [AppComponent]
})

appComponent.ts:

constructor(
        @Inject(MSAL_GUARD_CONFIG) private msalGuardConfig: MsalGuardConfiguration,
        private msalService: MsalService,
        private broadcastService: MsalBroadcastService,) { }

    ngOnInit(): void {
        this.isIframe = window !== window.parent && !window.opener;

        this.checkAccount();

        this.broadcastService.msalSubject$
            .pipe(
                filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS || msg.eventType === EventType.ACQUIRE_TOKEN_SUCCESS),
                takeUntil(this._destroying$)
            )
            .subscribe((result) => {
                this.checkAccount();
            });
    }

 checkAccount() {
        if (!this.userAccount) {
            var accounts = this.msalService.instance.getAllAccounts();

            if (accounts && accounts.length > 0) {
                this.loggedIn = true;
                this.userAccount = accounts[0];
                this.store.dispatch(new SetAsAuthenticated(this.userAccount));
            }
            else
                this.loggedIn = false;
        }
    }

    login() {
        if (this.msalGuardConfig.interactionType === InteractionType.Popup) {
            this.msalService.loginPopup({ ...this.msalGuardConfig.authRequest })
                .subscribe(() => this.checkAccount());
        } else {
            this.msalService.loginRedirect({ ...this.msalGuardConfig.authRequest });
        }
    }

    logout() {
        this.msalService.logout();
    }
// Provide configuration values here.
// For Azure B2C issues, please include your policies.

Reproduction steps

// Provide relevant code snippets here.
// For Azure B2C issues, please include your policies.

Expected behavior

Browsers/Environment

roopeshchinnakampalli commented 3 years ago

I think @azure/msal-angular@1.1.1 is for implicit flow version of MSAL. For this MSAL 2.x alpha, you may have to do configuration in the Azure Portal, like settings the app as SPA etc.,

This may help - https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-javascript-auth-code

jasonnutter commented 3 years ago

@DrRocket This error would seem to indicate that the window.crypto.subtle APIs are not present in your browser, can you please confirm if that is the case? Any further debugging you can do in your app would be helpful.

jasonnutter commented 3 years ago

And yes, please confirm that you have updated your app registration to support MSAL.js v2.

Dudleytmc commented 3 years ago

Yes, I can confirm that I updated the app registration in Azure AD to support MSAL.js v2.

I can also confirm that when I type in window.crypto.subtle in my browser console, it returns an object.
image

But I think you are on to something with the window.crypto.subtle, because after some more investigation, this error only happens on my root route when you type in the url without https:// after clearing the cache. My site is an Azure App that automatically redirects to https but for some reason, that initial load fails with this error before it switches to https. If I clear my cache and manually add in the https://, it loads fine.

I've tried this out on 5 different computers in both Edge and Chrome and get the same behavior.

jasonnutter commented 3 years ago

@DrRocket Ah, yes MSAL.js requires the crypto.subtle interface, which is only populated in secure contexts:

The read-only Window.crypto property returns the Crypto object associated to the global object. This object allows web pages access to certain cryptographic related services. Although the property itself is read-only, all of its methods (and the methods of its child object, SubtleCrypto) are not read-only, and therefore vulnerable to attack by polyfill.

Although window.crypto is available on all windows, the returned Crypto object only has one usable feature in insecure contexts: the getRandomValues() method. In general, you should use this API only in secure contexts.

https://developer.mozilla.org/en-US/docs/Web/API/Window/crypto

It is also worth noting that AAD does not support http redirect URIs (other than localhost).

Dudleytmc commented 3 years ago

Thanks for this. Turned out that on the deployment slot in Azure that I was using to test this, I had failed to set the HTTPS only flag on the custom domain. Setting this to true seems to have fixed this issue. Thanks for leading me to the answer!

image