Angular应用陷入无限循环

时间:2019-01-29 01:37:39

标签: angular typescript azure-active-directory microsoft-graph msal

我有一个使用@ microsoft / microsoft-graph-client来获取登录用户信息的Angular Web应用程序。 @ 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()时,整个应用程序将挂起,弹出窗口永远不会关闭,并且似乎永远不会进行身份验证并重定向回我的页面。我不确定为什么会这样。谁能看到任何明显的错误?

编辑

我要保留上面的内容,因为这是我的原始问题。我意识到问题与我的原始标题无关,因此更改了问题的名称。

2 个答案:

答案 0 :(得分:0)

我解决了我的问题,这与使用Azure AD或Graph API无关。在我的组件html中,我有一个* ngIf用来寻找函数的结果。看起来像这样:

<a mat-list-item *ngIf="authService.functionThatReturnsBoolean()" [routerLink]="['/SomeRoute']" routerLinkActive="router-link-active">Link Name</a>

相反,我更改了服务,以将结果填充到该服务的一个属性中,并将* ngIf指向该属性,如下所示:

<a mat-list-item *ngIf="authService.booleanProperty" [routerLink]="['/SomeRoute']" routerLinkActive="router-link-active">Link Name</a>

问题与Angular继续在* ngIf中查找状态的方式有关。然后它陷入了一个无休止的循环,直到Chrome崩溃。

答案 1 :(得分:0)

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

我认为问题在那里。如果您查看this.authorityInstance.ResolveEndpointsAsync()成功的回调函数,就会发现它是否为if

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

很明显,该弹出窗口将重定向到您的重定向URL。而且它永远不会像失败回调那样关闭该弹出窗口。我的快速而肮脏的修复方法是像这样修改它

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