如何配置 @azure/msal-angular 以使用路由器的导航函数进行客户端导航

默认情况下,当 MSAL.js 需要从应用程序中的一个页面导航到另一个页面时,它将重新分配 window.location,从而导致整个帧重定向到另一个页面,并导致应用程序重新呈现。 如果你使用的是 Angular Router,这可能并不理想,因为 Router 会启用“客户端”导航,并且仅按需显示或隐藏页面的相应部分。

目前,有一种情况是,MSAL.js 将从应用程序中的一个页面导航到另一个页面。 如果应用程序正在执行 以下所有 操作,请继续阅读:

  • 你的应用正在使用重定向流程而非弹出窗口流程进行登录
  • PublicClientApplication 配置为 auth.navigateToLoginRequestUrl: true(默认)
  • 你的应用程序中有些页面可能会调用 loginRedirect/acquireTokenRedirect,并共享一个 redirectUri,即:你从 http://localhost/protected 调用 loginRedirect,其 redirectUri 为 http://localhost

如果应用程序正在执行上述所有操作,则可以通过导入 MsalCustomNavigationClient 和调用 setNavigationClient来替代 MSAL 用于导航的方法。

注意:由于一项安全修复,当 navigateToLoginRequestUrl 设为 true 且处理重定向时,MsalCustomNavigationClient 将不会使用 Angular Router 进行客户端导航。 这是将在将来的版本中解决的已知问题。

示例实现

下面的示例将演示如何在使用 Angular Router时实现此内容。 有关 Angular Router 的更多信息可在此处找到,你还可以在此处找到一个实现此功能的完整 Angular 示例应用

import { Component, OnInit, Inject } from '@angular/core';
import { Router } from '@angular/router';
import { Location } from '@angular/common';
import { MsalService, MsalBroadcastService, MSAL_GUARD_CONFIG, MsalGuardConfiguration, MsalCustomNavigationClient } from '@azure/msal-angular';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {

  constructor(
    @Inject(MSAL_GUARD_CONFIG) private msalGuardConfig: MsalGuardConfiguration,
    private authService: MsalService,
    private msalBroadcastService: MsalBroadcastService,
    private router: Router,
    private location: Location
  ) {
    const customNavigationClient = new MsalCustomNavigationClient(this.authService, this.router, this.location);
    this.authService.instance.setNavigationClient(customNavigationClient);
  }

  ngOnInit(): void {
    // Additional code
  }
}