You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 16集成MSAL 3启动报错:需先调用initialize函数

Angular 16 + MSAL 3 启动报错:未初始化PublicClientApplication

启动开发服务器加载应用时,直接抛出以下错误:

You must call and await the initialize function before attempting to call any other MSAL API

我已经在AppComponent的ngOnInit中先调用this.authService.instance.initialize(),再处理handleRedirectPromise(),且相同代码在本地运行完全正常。查了MSAL官方文档,该错误仅会在调用login、acquireToken或handleRedirectPromise等API前未执行initialize时触发;也参考过类似的问题案例,但那个案例是点击按钮触发错误,和我启动应用即报错的场景不符,特此寻求解决方案。


app.module.ts 代码

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MsalModule, MsalService, MSAL_INSTANCE, MsalInterceptor, MsalGuard } from '@azure/msal-angular';
import {
  PublicClientApplication,
  InteractionType,
} from '@azure/msal-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { PublicPageComponent } from './public-page/public-page.component';
import { RestrictedPageComponent } from './restricted-page/restricted-page.component';
import { AddUserComponent } from './add-user/add-user.component';
import { FormsModule } from '@angular/forms';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { ListTeamsComponent } from './list-teams/list-teams.component';
import { HomePageComponent } from './Pages/home-page/home-page.component';
import { NavbarComponent } from './Pages/Partial/navbar/navbar.component';
import { AppLayoutModule } from './layout/app.layout.module';
import { SearchUserComponent } from './search-user/search-user.component';
import { NgxJsonViewerModule } from 'ngx-json-viewer';
import { environment } from '../environments/environment';


@NgModule({
  declarations: [
    AppComponent,
    PublicPageComponent,
    RestrictedPageComponent,
    AddUserComponent,
    ListTeamsComponent,
    HomePageComponent,
    NavbarComponent,
    SearchUserComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    MsalModule.forRoot(
      new PublicClientApplication({
        auth: {
          clientId: environment.AzureAppClientId,
          redirectUri: environment.redirectURL,
          authority:
            'https://login.microsoftonline.com/' + environment.AzureTenantId,
        },
        cache: {
          cacheLocation: 'sessionStorage',
          storeAuthStateInCookie: false,
        },
        system: {
          allowNativeBroker: false, // Disables native brokering support
        },
      }),
      {
        interactionType: InteractionType.Popup,
        authRequest: {
          scopes: ['user.read'],
        },
      },
      {
        interactionType: InteractionType.Popup,
        protectedResourceMap: new Map([
          ['https://graph.microsoft.com/v1.0/me', ['user.Read']],
          [environment.ProtectedAPIServer, [environment.ProtedtedAPIScope]],
        ]),
      }
    ),
    FormsModule,
    HttpClientModule,
    AppLayoutModule,
    NgxJsonViewerModule,
  ],
  providers: [
    MsalService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: MsalInterceptor,
      multi: true,
    },
    MsalGuard,
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

开发服务器环境文件

export const environment = {
  production: false,
  redirectURL: 'https://applicationURL.com',
  smartUCCAPIURL: 'https://applicationAPI.com/',
  AzureAppClientId: '123',
  AzureTenantId: 'T123',
  ProtectedAPIServer: 'https://applicationURL.com',
  ProtedtedAPIScope: 'api://abc/api.scope',
};

app.component.ts 代码

//https://github.com/AzureAD/microsoft-authentication-library-for-js
import { AuthenticationResult } from '@azure/msal-browser';
import { MsalService } from '@azure/msal-angular';
import { Component, OnInit } from '@angular/core';
import { environment } from '../environments/environment';
import { Message } from 'primeng/api';
import {
  faBook,
  faUser,
  faContactBook,
  faSearch,
  faTrowel,
  faHamburger,
  faAmbulance,
  faAnchorCircleCheck,
} from "@fortawesome/free-solid-svg-icons";
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { LayoutService } from 'src/app/layout/service/app.layout.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {
  title = 'test';
  searchIcon = faSearch;
  faHamburger = faHamburger;
  userIcon = faUser;
  userName = '';
  message: Message[] = [];
  showLeftNav: boolean = true;
  isAuthorized: boolean = true;
  showAndHideLeftNav() {
    this.showLeftNav = !this.showLeftNav;
  }

  constructor(
    private authService: MsalService,
    private http: HttpClient,
    public layoutService: LayoutService
  ) {}

  ngOnInit(): void {
    this.authService.instance.initialize();
    this.authService.instance.handleRedirectPromise().then((res) => {
      if (res != null && res.account != null) {
        this.authService.instance.setActiveAccount(res.account);
      }
    });
  }

  isLoggedIn(): boolean {
    //console.log(this.authService.instance.getActiveAccount());
    return this.authService.instance.getActiveAccount() != null;
  }

  IsAuthorized() {
    return this.isAuthorized;
  }

  showLogin() {
    this.isAuthorized = true;
  }
  login() {
    // this.authService.loginRedirect();

    this.authService
      .loginPopup()
      .subscribe((response: AuthenticationResult) => {
        console.log(response);

        const header = new HttpHeaders({ 'Access-Control-Allow-Origin': '*' });

        this.http
          .get(
            environment.apiURL+
              'api/User/IsUserAuthorized?userAZID=' +
              response.account.localAccountId
          )
          .subscribe((resp) => {
            if (resp) {
              sessionStorage.setItem(
                'loggedUserID',
                response.account.localAccountId
              );
              
              this.userName = response.account.username;
              this.authService.instance.setActiveAccount(response.account);
              this.isAuthorized = true;
            }else{
              this.isAuthorized = false;
            }
          });
      });
  }

  logout() {
    this.authService.logoutPopup({
      mainWindowRedirectUri: '/',
    });
  }
}

内容的提问来源于stack exchange,提问作者TechTurtle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 13:05:56