高层问题
我有一个成功连接到 Azure AD 应用程序进行身份验证的 Angular 应用程序。到目前为止,这完全没有问题。问题是当我尝试执行注销功能时。我认为这个问题源于我如何在我的 Angular 应用程序中实例化 MSAL 库。
背景和代码
下面是我的app.component.ts的部分代码。有一个配置服务可以读取本地 JSON 文件以获取 Azure clientID、applicationID 等信息。这是JsonConfigService的一部分。一旦 NgInit 运行,我们还会从CompanyApi获取信息,该信息提供登录用户的名称、他们的姓名等信息,并将其显示在整个应用程序中存在的标题上(因此,它位于app.component.ts文件)。这个标题有一个汉堡菜单,由下面的 JSON 填充,应该是直观的。
import { MsalService } from '@azure/msal-angular';
import { JsonConfigService } from 'companylib/common-ng/common';
import { HamburgerItem } from 'companylib/common-ng/app-header';
...
private _securedApplication : IPublicClientApplication = null;
private appSettings: IAppSettings = null;
constructor( private _cfgSvc: JsonConfigService<IAppSettings>,
private _headerSvc: HeaderDetailsService
private _companyApi: CompanyApi
private _msalAuthService: MsalService) {
this._securedApplication = _msalAuthService.instance;
}
...
public ngOnInit() {
this._cfgSvc.config.subscribe(cfg => {
this.appSettings = cfg;
});
this._companyApi.getUserDetails().subscribe(details => {
this._headerSvc.updateUser(details.nameFull, details.pictureUrl);
if (this.appSettings) {
this.title = this.appSettings.title;
this._headerSvc.updateHeader({
title: this.appSettings.title,
environment: this.appSettings.environment,
version: this.appSettings.version,
menuItems: [
{
path: '/',
text: 'Home'
},
{
path: 'AdminPage',
text: 'Administration Page'
},
{
hrule: true,
actionText: 'Logout',
action: this.logoff
}
],
});
};
});
}
...
logoff() {
this._securedApplication.logoutRedirect();
}
运行时的问题:
如果我在NgInit()上设置断点,我可以确认_msalAuthService和实例属性中都有一个对象。伟大的。但是,当我单击 Logout() 的 Hamburger 链接时,this._securedApplication是未定义的。此类中没有其他代码可以删除this._securedApplication。同样,clientid 等都很好。有效令牌已通过,我可以看到网络流量。
我认为问题出在哪里
为了适应从配置文件中读取,MsalModule 和各种模块被加载到app.module.ts文件的Providers部分。它看起来像这样:
**app.module.ts** (abbreviated)
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
BrowserAnimationsModule,
...
CompanyCommonModule,
AppHeaderModule,
ToastrModule.forRoot(),
...
NgbModule
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: (auth: AuthService) => () => auth.Load(),
deps: [AuthService],
multi: true },
{ provide: DefaultJsonConfigFactory, useExisting: DefaultSettingsFactory },
{ provide: MappableTokenProviderService, useExisting: ResourceIdAdditionalHeaderService },
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true
},
mlCommonHttpInterceptorProviders,
{
provide: HTTP_INTERCEPTORS,
useClass: AdditionalHeadersInterceptor,
multi: true
},
{
provide: MSAL_INSTANCE,
useFactory: MSALInstanceFactory,
deps: [AuthService]
},
{
provide: MSAL_INTERCEPTOR_CONFIG,
useFactory: MSALInterceptorConfigFactory,
deps: [AuthService]
},
{
provide: MSAL_GUARD_CONFIG,
useFactory: MSALGuardConfigFactory,
deps: [AuthService]
},
MsalService,
MsalGuard,
MsalBroadcastService,
],
bootstrap: [AppComponent, MsalRedirectComponent ]
...
and some exported functions:
export function MSALInstanceFactory(_authService: AuthService): IPublicClientApplication {
return new PublicClientApplication(_authService.GetConfiguration());
}
export function MSALInterceptorConfigFactory(_authService: AuthService): MsalInterceptorConfiguration {
return {
interactionType: InteractionType.Redirect,
protectedResourceMap : _authService.protectedResources
};
}
export function MSALGuardConfigFactory(_authService: AuthService): MsalGuardConfiguration {
return {
interactionType: InteractionType.Redirect,
authRequest: _authService.loginRequest
};
}
它似乎工作得很好,配置设置正确。我只是没有提到我认为是注入变量的东西。
我在这里做错了什么,有没有更好的方法来实现这一点?