Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I am getting an error when using a custom wrapper for MSAL 2.0

Here is the wrapper ts file

import { APP_INITIALIZER, InjectionToken, NgModule } from '@angular/core';
import { LogLevel, Configuration, BrowserCacheLocation, InteractionType, IPublicClientApplication, PublicClientApplication } from '@azure/msal-browser';
import { ConfigService } from './shared/services/config.service';
import jsonconfig from '../assets/environment/conf.json'
import { MatDialogRef } from '@angular/material/dialog';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { MsalBroadcastService, MsalGuard, MsalGuardConfiguration, MsalInterceptor, MsalInterceptorConfiguration, MsalModule, MsalService, MSAL_GUARD_CONFIG, MSAL_INSTANCE, MSAL_INTERCEPTOR_CONFIG } from '@azure/msal-angular';
 const isIE = window.navigator.userAgent.indexOf("MSIE ") > -1 || window.navigator.userAgent.indexOf("Trident/") > -1;
 const AUTH_CONFIG_URL_TOKEN = new InjectionToken<string>('AUTH_CONFIG_URL');
 export function initializerFactory(env: ConfigService): any {
     // APP_INITIALIZER, except a function return which will return a promise
     // APP_INITIALIZER, angular doesnt starts application untill it completes
     const promise = env.init().then((value) => {
         console.log(env.getSettings('clientID'));
     return () => promise;
 export function MSALInstanceFactory(conf:ConfigService): IPublicClientApplication {
     const configuration:Configuration={
     auth: {
         clientId: conf.getSettings("clientId"), // This is the ONLY mandatory field that you need to supply.
         authority: 'https://login.microsoftonline.com/'+ conf.getSettings("tenentId"), // Defaults to "https://login.microsoftonline.com/common"
         redirectUri: conf.getSettings("redirectUri"), // Points to window.location.origin. You must register this URI on Azure portal/App Registration.
         postLogoutRedirectUri: '/', // Indicates the page to navigate after logout.
         navigateToLoginRequestUrl: true, // If "true", will navigate back to the original request location before processing the auth code response.
     cache: {
         cacheLocation: BrowserCacheLocation.LocalStorage, // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO between tabs.
         storeAuthStateInCookie: isIE, // Set this to "true" if you are having issues on IE11 or Edge
     system: {
         loggerOptions: {
             loggerCallback(logLevel: LogLevel, message: string) {
                 console.log(message);
             logLevel: LogLevel.Verbose,
             piiLoggingEnabled: false
    return new PublicClientApplication(configuration);
 export const silentRequest = {
     scopes: ["openid", "profile"],
     loginHint: "example@domain.net"
export const loginRequest = {
    scopes: []
  export function MSALInterceptorConfigFactory(conf:ConfigService): MsalInterceptorConfiguration {
    const protectedResources:Map<string, Array<string>>=new Map([
        ['https://graph.microsoft.com/v1.0/me', ['user.read']],
          'api',
          [conf.getSettings("apiClientId") + '/user_impersonation'],
    return {
      interactionType: InteractionType.Redirect,
      protectedResourceMap: protectedResources
  export function MSALGuardConfigFactory(): MsalGuardConfiguration {
    return { 
      interactionType: InteractionType.Redirect,
      authRequest: loginRequest
//-------------------------------------------------------------
@NgModule({
    providers: [
    imports: [MsalModule]
export class MsalConfModule{
    staticforroot() {
        return {
            providers: [
                { provide: AUTH_CONFIG_URL_TOKEN },
                { provide: APP_INITIALIZER, useFactory: initializerFactory,
                    deps: [ConfigService, 
                    AUTH_CONFIG_URL_TOKEN], 
                    multi: true 
                  provide: HTTP_INTERCEPTORS,
                  useClass: MsalInterceptor,
                  multi: true,
                  provide: MSAL_INSTANCE,
                  useFactory: MSALInstanceFactory,
                  deps: [ConfigService]
                  provide: MSAL_GUARD_CONFIG,
                  useFactory: MSALGuardConfigFactory
                  provide: MSAL_INTERCEPTOR_CONFIG,
                  useFactory: MSALInterceptorConfigFactory,
                  deps: [ConfigService]
                MsalService,
                MsalGuard,
                MsalBroadcastService

Here is the app module

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule,AppRoutingComonent } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'
import { MsalConfModule } from './authconfig';
const ngWizardConfig: NgWizardConfig = {
  theme: THEME.default
@NgModule({
  declarations: [
    AppComponent,
    AppRoutingComonent,
  imports: [
    BrowserModule,
    DataTablesModule,
    HttpClientModule,
    AppRoutingModule,
    MatDialogModule,
    BrowserAnimationsModule, // required animations module
    ToastrModule.forRoot(), // ToastrModule added,
    NgWizardModule.forRoot(ngWizardConfig),
    MsalConfModule
  providers: [
    provide: MatDialogRef,
    useValue: {}
  bootstrap: [AppComponent]
export class AppModule { 

There is no compile error. I am getting a run time error below

Based on J.Loscos answer I have updated the code, but now this error shows

Type '{ provide: InjectionToken<string>; }' is not assignable to type 'Provider'.
  Type '{ provide: InjectionToken<string>; }' is missing the following properties from type 'Type<any>'

The problem with your code is that you declare the injection tokens in the staticforroot method but you don't use this method.

It seems that you are trying to use the forRoot pattern for module import. To use this pattern, your staticforroot method in the module should return the module in addition of the providers :

@NgModule({
    providers: [
    imports: [MsalModule]
export class MsalConfModule{
    staticforroot() : ModuleWithProviders<MsalConfModule>  {
        return {
            ngModule: MsalConfModule,
            providers: [
                { provide: AUTH_CONFIG_URL_TOKEN },
                { provide: APP_INITIALIZER, useFactory: initializerFactory,
                    deps: [ConfigService, 
                    AUTH_CONFIG_URL_TOKEN], 
                    multi: true 

And when importing this module in your AppModule you need to call the staticforroot method :

@NgModule({
  declarations: [
    AppComponent,
    AppRoutingComonent,
  imports: [
    BrowserModule,
    MsalConfModule.staticforroot()
  providers: [
    provide: MatDialogRef,
    useValue: {}
  bootstrap: [AppComponent]
export class AppModule { 
                Thanks a lot for that suggestion. But I tried that and getting this error now Type '{ provide: InjectionToken<string>; }' is not assignable to type 'Provider'.   Type '{ provide: InjectionToken<string>; }' is missing the following properties from type 'Type<any>'. Will update the question with this details as well
– Sandeep Thomas
                Jun 28, 2021 at 13:44
                I think this error comes from the ` { provide: AUTH_CONFIG_URL_TOKEN }` because it doesn't have a use, useClass or useFactory
– J.Loscos
                Jun 28, 2021 at 13:52
                Based on the name of the injection token, I imagine it's intended to be the url of a config file. So you could do something like { provide: AUTH_CONFIG_URL_TOKEN, use: "https://yourbackend/config.json" } But I see that you declare this token as a dependency of the initializerFactory, but this factory doesn't use it. So if it's not used anywhere else you can also remove the provider and remove it from the initializerFactory dependencies
– J.Loscos
                Jun 28, 2021 at 14:03
                In my answer I added a property ngModule to the object returned by the staticforroot method. Did you include it in your code?
– J.Loscos
                Jun 28, 2021 at 14:54
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.