首页 > 解决方案 > Angular 应用程序陷入无限循环

问题描述

我有一个 Angular Web 应用程序,它使用 @microsoft/microsoft-graph-client 来获取登录用户的信息。@azure/msal-angular 用于登录用户。我有一个身份验证服务,它使用以下命令登录用户:

  async signIn(): Promise<void> {
    const result = await this.msalService.loginPopup(OAuthSettings.consentScopes)
      .catch((reason) => {
        this.alertsService.add('Login failed', JSON.stringify(reason, null, 2));
      });

    if (result) {
      this.authenticated = true;
      await this.getUser();
    }
  }
  private async getClient(): Promise<Client> {
    const graphClient = Client.init({
      // Initialize the Graph client with an auth
      // provider that requests the token from the
      // auth service
      authProvider: async (done) => {
        const token = await this.getAccessToken()
          .catch((reason) => {
            done(reason, null);
          });
        if (token) {
          done(null, token);
        } else {
          done('Could not get an access token', null);
        }
      }
    });
    return graphClient;
  }

private async getUser() {
    if (!this.authenticated) {
      return null;
    }
    const graphClient = await this.getClient();

    // Get the user from Graph (GET /me)
    const graphUser = await graphClient.api('/me').get();

    console.log('USERNAME: ', graphUser.displayName);
    sessionStorage.setItem('d365dataportal.user', graphUser);
    if (graphUser.mail != null) {
      sessionStorage.setItem('d365dataportal.user.email', graphUser.mail);
    } else {
      sessionStorage.setItem('d365dataportal.user.email', graphUser.userPrincipalName);
    }
    sessionStorage.setItem('d365dataportal.user.avatar', graphUser.avatar);
    sessionStorage.setItem('d365dataportal.user.name', graphUser.displayName);
  }

我的 OAuthSettings 如下所示:

export const OAuthSettings = {
  appId: 'App GUID from Azure Here',
  redirectUri: 'http://localhost:4200',
  consentScopes: ['user.read',
    'Directory.Read.All',
    'Directory.ReadWrite.All',
    'Directory.AccessAsUser.All']
};

我遇到的问题是,当 this.msalService.loginPopup() 被调用时,整个应用程序挂起,弹出窗口永远不会关闭,并且似乎永远不会进行身份验证并重定向回我的页面。我不确定为什么会这样。任何人都可以看到任何明显的错误吗?

编辑

我将离开上面的内容,因为这是我最初的问题。我意识到这个问题与我原来的标题无关,并更改了问题的名称。

标签: angulartypescriptazure-active-directorymicrosoft-graph-apimsal

解决方案


我进行了一些调试,我认为 MSAL 中存在我不理解的错误或功能。如果您查看 MSAL 库中的 UserAgentApplication.js,则此函数称为loginPopupHelper();

我认为问题是存在的。如果您查看this.authorityInstance.ResolveEndpointsAsync()成功的回调函数,您会发现这个 if 块

if (popUpWindow) {
    _this._logger.infoPii("Navigated Popup window to:" + urlNavigate);
    popUpWindow.location.href = urlNavigate;
}

它显然将该弹出窗口重定向到您的重定向网址。它永远不会像失败回调那样关闭那个弹出窗口。我快速而肮脏的解决方法是像这样修改它

if (popUpWindow) {
    _this._logger.infoPii("Navigated Popup window to:" + urlNavigate);
    window.location.href = urlNavigate;
    popUpWindow.close();
}

不用说,这不是稳定的解决方案,因为每当您更新该库时,我猜它都会被覆盖。此外,这不再触发弹出窗口,而是重定向到 MS 登录页面,然后在给出凭据时返回。我知道为什么会发生这种情况,但现在没有时间。如果还没有讨论,我想我会在 Github 上开始讨论这个问题。

但是,是的,这就是我能够找到的。

编辑:实际上 Github 中已经有一些与此相关的内容。例如

https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/545

https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/479


推荐阅读