Angular单页应用程式 (SPA)+Azure AD重新导向登入

一.app.module.ts中设定应用程式

1.将MSAL Angular相关设置封装为auth.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MsalGuard, MsalBroadcastService, MsalModule, MsalService, MSAL_GUARD_CONFIG, MSAL_INSTANCE, MsalGuardConfiguration, MsalRedirectComponent } from '@azure/msal-angular';
import { IPublicClientApplication, PublicClientApplication, InteractionType } from '@azure/msal-browser';
import { LogLevel, Configuration, BrowserCacheLocation } from '@azure/msal-browser';

const isIE = window.navigator.userAgent.indexOf("MSIE ") > -1 || window.navigator.userAgent.indexOf("Trident/") > -1;


export function MSALInstanceFactory(): IPublicClientApplication {
  return new PublicClientApplication( {
    auth: {
        clientId: '', // 应用clientId
        authority: 'https://login.microsoftonline.com/common',,
        redirectUri: '',
    },
    cache: {
        cacheLocation: BrowserCacheLocation.LocalStorage, // LocalStorage缓存
        storeAuthStateInCookie: isIE, // IE11或Edge上遇到问题
    },
});
}

export function MSALGuardConfigFactory(): MsalGuardConfiguration {
  return {
    interactionType: InteractionType.Redirect,
  };
}

@NgModule({
  declarations: [],
  imports: [
    MsalModule,
    CommonModule
  ],
  providers: [
    {
      provide: MSAL_INSTANCE,
      useFactory: MSALInstanceFactory
    },
    {
      provide: MSAL_GUARD_CONFIG,
      useFactory: MSALGuardConfigFactory
    },
    MsalService,
    MsalGuard,
    MsalBroadcastService,
  ],
})
export class AuthModule { }
View Code

2.app.module.ts引入auth.module.ts;同时引入MsalRedirectComponent 重新导向组件

import { AppComponent } from './app.component';
import { AuthModule } from './auth/auth.module';
import {MsalRedirectComponent } from '@azure/msal-angular';//导入处理重新导向的组件

@NgModule({
  declarations: [
    ...
    AppComponent,
  ],
  imports: [
    ...
    AuthModule,
  ],
  bootstrap: [AppComponent,MsalRedirectComponent],
})
View Code

3.將 <app-redirect> 选取器新增至 src/index.html。 此选取器是由 MsalRedirectComponent 使用

4.登录;订阅LOGIN_SUCCESS 事件。 可从使用重新导向的成功登入存取結果

import { Component, OnInit } from '@angular/core';
import { MsalBroadcastService, MsalService } from '@azure/msal-angular';
import { AuthenticationResult, EventMessage, EventType, InteractionStatus } from '@azure/msal-browser';
import { Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';


@Component({
  selector: 'app-home-page',
  templateUrl: './home-page.component.html',
  styleUrls: ['./home-page.component.scss']
})
export class HomePageComponent implements OnInit {

  private readonly _destroying$ = new Subject<void>();
  username: string | undefined;
 

  constructor(
    private authService: MsalService,
    private msalBroadcastService: MsalBroadcastService
  ) { }

  ngOnInit(): void {
    this.msalBroadcastService.msalSubject$
    .pipe(
      filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS),
      takeUntil(this._destroying$)
    )
    .subscribe((result: EventMessage) => {
      const payload = result.payload as AuthenticationResult;
      this.authService.instance.setActiveAccount(payload.account)
      this.setLoginDisplay();
    });

    this.setLoginDisplay();
  }

  setLoginDisplay(){
    if(this.authService.instance.getAllAccounts().length > 0){
      this.username = this.authService.instance.getAllAccounts()[0].name;
    }
  }

  login(){
    this.authService.loginRedirect();
  }

  logout() {
    this.authService.logoutRedirect();
  }


}
View Code

5.根据重新导向的成功登入結果定义路由守卫

import { MsalService } from '@azure/msal-angular';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate,  RouterStateSnapshot, UrlTree } from '@angular/router';
import { concatMap, catchError, map } from 'rxjs/operators';
import { Observable, of } from 'rxjs';


@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  constructor(
    private authService: MsalService,
    ) { }

  canActivate(
    route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
    Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
      return this.authService.handleRedirectObservable()
      .pipe(
          concatMap(() => {
              if (!this.authService.instance.getAllAccounts().length) {
                this.authService.loginRedirect();
                return of(false);
              }
              return of(true);
          }),
          catchError(() =>{
            return of(false)
          } )
      );
  }
}
View Code

 

posted @ 2022-04-24 16:05  艺洁  阅读(146)  评论(0编辑  收藏  举报