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

Angular开发Teams Tab应用的Microsoft Entra认证异常问题

Angular Teams Tab 认证异常:弹窗认证完成后主应用未同步登录状态

环境依赖

  • @azure/msal-angular: 3.0.12
  • @azure/msal-browser: 3.9.0
  • @microsoft/teams-js: 2.20.0

问题描述

Web端基于Angular+Microsoft Entra的认证完全正常,通过MsalService的loginPopup/loginRedirect可正常完成认证。但在Teams Tab应用中,使用@microsoft/teams-js的authentication.authenticate()发起认证后,出现以下异常:

  • 认证流程能正常走完,auth-end组件执行authentication.notifySuccess返回正确的tokenResponse,弹窗正常关闭
  • 弹窗关闭后,主应用仍处于未认证状态,手动调用msalService.instance.setActiveAccount()也无法同步登录状态
  • 测试确认:认证弹窗内部可正常完成认证,能访问受MsalGuard保护的组件,但主应用无任何状态同步

核心代码

主应用认证调用(app.component.ts)

authentication.authenticate({ 
    url: window.location.origin + "/auth-start", 
    width: 600, 
    height: 535 
}) 
.then((result) => { 
    console.log("Login succeeded: " + result); 
}) 
.catch((reason) => { 
    console.log("Login failed: " + reason); 
});

auth-start组件代码

ngOnInit(): void { 
    this.msalService.handleRedirectObservable().subscribe(); 
    app.getContext().then(async (context) => { 
        this.loginRedirect(context.user?.loginHint); 
    }); 
} 

loginRedirect(loginHint?: string) { 
    let req = { ...this.msalGuardConfig.authRequest } as RedirectRequest; 
    req.loginHint = loginHint; 
    req.redirectUri = window.location.origin + `/auth-end`; 
    this.msalService.loginRedirect(req); 
}

auth-end组件代码

ngOnInit(): void { 
    app.getContext().then(async (context) => { 
        await this.msalInstance.initialize(); 

        await this.msalInstance.handleRedirectPromise() 
            .then((tokenResponse) => { 
                if (tokenResponse !== null) { 
                    authentication.notifySuccess(JSON.stringify(tokenResponse)); 
                } else { 
                    authentication.notifyFailure("Get empty response."); 
                } 
            }) 
            .catch((error) => { 
                authentication.notifyFailure(JSON.stringify(error)); 
            }); 
    }); 
}

MSAL配置(Web端正常,Teams端无效)

export function MSALInstanceFactory(): IPublicClientApplication {
  return new PublicClientApplication({
    auth: {
      clientId: environment.msalConfig.auth.clientId,
      authority: environment.msalConfig.auth.authority,
      redirectUri: '/',
      postLogoutRedirectUri: '/',
      navigateToLoginRequestUrl: false
    },
    cache: {
      cacheLocation: BrowserCacheLocation.SessionStorage
    },
    system: {
      allowNativeBroker: false, // Disables WAM Broker
      loggerOptions: {
        loggerCallback,
        logLevel: LogLevel.Info,
        piiLoggingEnabled: false
      }
    }
  });
}

export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
  const protectedResourceMap = new Map<string, Array<string>>([
    [environment.graphConfig.uri, environment.graphConfig.scopes],
    [environment.apiUrl, environment.apiScopes]
  ]);

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

export function MSALGuardConfigFactory(): MsalGuardConfiguration {
  return {
    interactionType: InteractionType.Redirect,
    authRequest: {
      scopes: [...environment.graphConfig.scopes]
    },
    loginFailedRoute: '/login-failed'
  };
}

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideClientHydration(),
    provideAnimationsAsync(),
    provideHttpClient(withInterceptors([errorInterceptor]), withInterceptorsFromDi()),
    {
      provide: HTTP_INTERCEPTORS,
      useClass: MsalInterceptor,
      multi: true
    },
    {
      provide: MSAL_INSTANCE,
      useFactory: MSALInstanceFactory
    },
    {
      provide: MSAL_GUARD_CONFIG,
      useFactory: MSALGuardConfigFactory
    },
    {
      provide: MSAL_INTERCEPTOR_CONFIG,
      useFactory: MSALInterceptorConfigFactory
    },
    MsalService,
    MsalGuard,
    MsalBroadcastService,
    { provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: { appearance: 'outline' } },
    provideNativeDateAdapter(),
    { provide: MAT_DATE_LOCALE, useValue: 'en-GB' }
  ]
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:23:15