【问题标题】:App Module Provider throws NullInjectorError: No provider for InjectionToken MSAL_GUARD_CONFIGApp Module Provider 抛出 NullInjectorError: No provider for InjectionToken MSAL_GUARD_CONFIG
【发布时间】:2021-09-10 18:18:41
【问题描述】:

我有这样的配置包装器用于 Azure AD 身份验证

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 {
    const auth= { 
      interactionType: InteractionType.Redirect,
      authRequest: loginRequest
    };
    return(auth as MsalGuardConfiguration)
  }
//-------------------------------------------------------------
@NgModule({
    providers: [
    ],
    imports: [MsalModule]
})
export class MsalConfModule{
    static forRoot() {
        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
            ],
        }
    }

}

我正在尝试在 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,

    AppRoutingModule,

    MsalConfModule
  ],
  providers: [
    {
    provide: MatDialogRef,
    useValue: {}
    }
],
  bootstrap: [AppComponent]
})
export class AppModule { 
  
}

但是编译时没有错误。我收到运行时错误提示

main.ts:12 NullInjectorError: R3InjectorError(AppModule)[InjectionToken MSAL_GUARD_CONFIG -> InjectionToken MSAL_GUARD_CONFIG -> InjectionToken MSAL_GUARD_CONFIG]: NullInjectorError: 没有 InjectionToken MSAL_GUARD_CONFIG 的提供者!

我不明白我做错了什么。请帮忙

根据 Brian 的回答,我尝试在 app 模块中添加这样的 forRoot

MsalConfModule.forRoot()

但这引发了编译错误

Type '{ providers: (typeof MsalService | typeof MsalGuard | typeof MsalBroadcastService | { provide: InjectionToken<string>; useFactory?: undefined; deps?: undefined; multi?: undefined; useClass?: undefined; } | ... 4 more ... | { ...; })[]; }' is not assignable to type 'any[] | Type<any> | ModuleWithProviders<{}>'.
  Property 'ngModule' is missing in type '{ providers: (typeof MsalService | typeof MsalGuard | typeof MsalBroadcastService | { provide: InjectionToken<string>; useFactory?: undefined; deps?: undefined; multi?: undefined; useClass?: undefined; } | ... 4 more ... | { ...; })[]; }' but required in type 'ModuleWithProviders<{}>'.ts(2322)
core.d.ts(4279, 5): 'ngModule' is declared here.

我错过了,我的 Angular 版本 11.0

【问题讨论】:

    标签: angular azure azure-active-directory


    【解决方案1】:

    确保将您的 app.module.ts 中的 forRoot() 添加到 MsalConfModule,因为您有一个带有提供程序的模块。

    app.module.ts

    MsalConfModule.forRoot()
    

    使用以下内容更新您的forRoot()

    export class MsalConfModule{
      static forRoot(): ModuleWithProviders<MsalConfModule> {
          return {
            ngModule: MsalConfModule,
              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
              ],
          }
      }
    
    }
    

    【讨论】:

    • 对不起朋友.. 我刚试过,但没有用。还是一样的错误
    • 用另一件事更新了我的答案
    • 这会触发一个编译错误,这个错误有点长,所以我正在更新我的问题
    • 在尝试了您提到的观点后刚刚更新了我的问题。
    猜你喜欢
    • 1970-01-01
    • 2019-01-24
    • 2022-12-27
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 2018-10-14
    • 2018-08-27
    • 2021-10-16
    相关资源
    最近更新 更多