Włączanie uwierzytelniania we własnej aplikacji Angular przy użyciu usługi Azure Active Directory B2C

W tym artykule przedstawiono sposób dodawania uwierzytelniania usługi Azure Active Directory B2C (Azure AD B2C) do własnej aplikacji Angular jednostronicowej (SPA). Dowiedz się, jak zintegrować aplikację Angular z biblioteką MSAL dla biblioteki uwierzytelniania Angular.

Skorzystaj z tego artykułu z powiązanym artykułem Konfigurowanie uwierzytelniania w przykładowej aplikacji jednostronicowej Angular. Zastąp przykładową aplikację Angular własną aplikacją Angular. Po wykonaniu kroków opisanych w tym artykule aplikacja zaakceptuje logowania za pośrednictwem usługi Azure AD B2C.

Wymagania wstępne

Wykonaj kroki opisane w artykule Konfigurowanie uwierzytelniania w przykładowej aplikacji Angular jednostronicowej.

Tworzenie projektu aplikacji Angular

Możesz użyć istniejącego projektu aplikacji Angular lub utworzyć nowy. Aby utworzyć nowy projekt, uruchom następujące polecenia.

Polecenia:

  1. Zainstaluj interfejs wiersza polecenia Angular przy użyciu menedżera pakietów npm.
  2. Utwórz obszar roboczy Angular za pomocą modułu routingu. Nazwa aplikacji to msal-angular-tutorial. Można go zmienić na dowolną prawidłową nazwę aplikacji Angular, na przykład contoso-car-service.
  3. Przejdź do folderu katalogu aplikacji.
npm install -g @angular/cli 
ng new msal-angular-tutorial --routing=true --style=css --strict=false
cd msal-angular-tutorial

Instalowanie zależności

Aby zainstalować biblioteki msAL Browser i MSAL Angular w aplikacji, uruchom następujące polecenie w powłoce poleceń:

npm install @azure/msal-browser @azure/msal-angular

Zainstaluj bibliotekę składników Angular Material (opcjonalnie dla interfejsu użytkownika):

npm install @angular/material @angular/cdk

Dodawanie składników uwierzytelniania

Przykładowy kod składa się z następujących składników:

Składnik Typ Opis
auth-config.ts Stałe Ten plik konfiguracji zawiera informacje o dostawcy tożsamości usługi Azure AD B2C i usłudze internetowego interfejsu API. Aplikacja Angular używa tych informacji do ustanowienia relacji zaufania z usługą Azure AD B2C, zaloguj się i wyloguj użytkownika, uzyskaj tokeny i zweryfikuj tokeny.
app.module.ts moduł Angular W tym składniku opisano, jak części aplikacji pasują do siebie. Jest to moduł główny używany do uruchamiania i otwierania aplikacji. W tym przewodniku dodasz niektóre składniki do modułu app.module.ts i uruchomisz bibliotekę MSAL za pomocą obiektu konfiguracji biblioteki MSAL.
app-routing.module.ts moduł routingu Angular Ten składnik umożliwia nawigację przez interpretowanie adresu URL przeglądarki i ładowanie odpowiedniego składnika. W tym przewodniku dodasz niektóre składniki do modułu routingu i chronisz składniki za pomocą funkcji MSAL Guard. Tylko autoryzowani użytkownicy mogą uzyskiwać dostęp do chronionych składników.
app.component.* składnik Angular Polecenie ng new utworzyło projekt Angular z składnikiem głównym. W tym przewodniku zmienisz składnik aplikacji na hostowanie górnego paska nawigacyjnego. Pasek nawigacyjny zawiera różne przyciski, w tym przyciski logowania i wylogowywanie. Klasa app.component.ts obsługuje zdarzenia logowania i wylogowywanie.
home.component.* składnik Angular W tym przewodniku dodasz składnik macierzysty , aby renderować stronę główną na potrzeby dostępu anonimowego. Ten składnik pokazuje, jak sprawdzić, czy użytkownik zalogował się.
profile.component.* składnik Angular W tym przewodniku dodasz składnik profilu , aby dowiedzieć się, jak odczytywać oświadczenia tokenu identyfikatora.
webapi.component.* składnik Angular W tym przewodniku dodasz składnik webapi , aby dowiedzieć się, jak wywołać internetowy interfejs API.

Aby dodać następujące składniki do aplikacji, uruchom następujące polecenia interfejsu wiersza polecenia Angular. Polecenia generate component :

  1. Utwórz folder dla każdego składnika. Folder zawiera pliki TypeScript, HTML, CSS i testowe.
  2. app.module.ts Zaktualizuj pliki i app-routing.module.ts przy użyciu odwołań do nowych składników.
ng generate component home
ng generate component profile
ng generate component webapi

Dodawanie ustawień aplikacji

Ustawienia dostawcy tożsamości usługi Azure AD B2C i internetowego interfejsu API są przechowywane w pliku auth-config.ts. W folderze src/app utwórz plik o nazwie auth-config.ts zawierający następujący kod. Następnie zmień ustawienia zgodnie z opisem w sekcji 3.1 Konfigurowanie przykładu Angular.

import { LogLevel, Configuration, BrowserCacheLocation } from '@azure/msal-browser';

const isIE = window.navigator.userAgent.indexOf("MSIE ") > -1 || window.navigator.userAgent.indexOf("Trident/") > -1;
 
export const b2cPolicies = {
     names: {
         signUpSignIn: "b2c_1_susi_reset_v2",
         editProfile: "b2c_1_edit_profile_v2"
     },
     authorities: {
         signUpSignIn: {
             authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_susi_reset_v2",
         },
         editProfile: {
             authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_edit_profile_v2"
         }
     },
     authorityDomain: "your-tenant-name.b2clogin.com"
 };
 
 
export const msalConfig: Configuration = {
     auth: {
         clientId: '<your-MyApp-application-ID>',
         authority: b2cPolicies.authorities.signUpSignIn.authority,
         knownAuthorities: [b2cPolicies.authorityDomain],
         redirectUri: '/', 
     },
     cache: {
         cacheLocation: BrowserCacheLocation.LocalStorage,
         storeAuthStateInCookie: isIE, 
     },
     system: {
         loggerOptions: {
            loggerCallback: (logLevel, message, containsPii) => {
                console.log(message);
             },
             logLevel: LogLevel.Verbose,
             piiLoggingEnabled: false
         }
     }
 }

export const protectedResources = {
  todoListApi: {
    endpoint: "http://localhost:5000/api/todolist",
    scopes: ["https://your-tenant-name.onmicrosoft.com/api/tasks.read"],
  },
}
export const loginRequest = {
  scopes: []
};

Uruchamianie bibliotek uwierzytelniania

Publiczne aplikacje klienckie nie są zaufane do bezpiecznego przechowywania wpisów tajnych aplikacji, więc nie mają wpisów tajnych klienta. W folderze src/app otwórz plik app.module.ts i wprowadź następujące zmiany:

  1. Zaimportuj biblioteki msAL Angular i przeglądarki MSAL.
  2. Zaimportuj moduł konfiguracji Azure AD B2C.
  3. Zaimportuj HttpClientModuleplik . Klient HTTP służy do wywoływania internetowych interfejsów API.
  4. Zaimportuj Angular przechwytywania HTTP. Biblioteka MSAL używa przechwytywania do wstrzykiwania tokenu elementu nośnego do nagłówka autoryzacji HTTP.
  5. Dodaj niezbędne materiały Angular.
  6. Utwórz wystąpienie biblioteki MSAL przy użyciu obiektu aplikacji klienckiej z wieloma kontami publicznymi. Inicjowanie biblioteki MSAL obejmuje przekazywanie:
    1. Obiekt konfiguracji dla pliku auth-config.ts.
    2. Obiekt konfiguracji dla funkcji routingu.
    3. Obiekt konfiguracji przechwytywania biblioteki MSAL. Klasa przechwytywania automatycznie uzyskuje tokeny dla żądań wychodzących, które używają klasy Angular HttpClient do znanych chronionych zasobów.
  7. HTTP_INTERCEPTORS Skonfiguruj dostawców Angular iMsalGuard.
  8. Dodaj MsalRedirectComponent do Angular bootstrap.

W folderze src/app zmodyfikuj plik app.module.ts i wprowadź modyfikacje pokazane w poniższym fragmencie kodu. Zmiany są oflagowane za pomocą polecenia "Zmiany zaczynają się tutaj" i "Zmiany zakończą się tutaj".

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

/* Changes start here. */
// Import MSAL and MSAL browser libraries. 
import { MsalGuard, MsalInterceptor, MsalModule, MsalRedirectComponent } from '@azure/msal-angular';
import { InteractionType, PublicClientApplication } from '@azure/msal-browser';

// Import the Azure AD B2C configuration 
import { msalConfig, protectedResources } from './auth-config';

// Import the Angular HTTP interceptor. 
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { ProfileComponent } from './profile/profile.component';
import { HomeComponent } from './home/home.component';
import { WebapiComponent } from './webapi/webapi.component';

// Add the essential Angular materials.
import { MatButtonModule } from '@angular/material/button';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatListModule } from '@angular/material/list';
import { MatTableModule } from '@angular/material/table';
/* Changes end here. */

@NgModule({
  declarations: [
    AppComponent,
    ProfileComponent,
    HomeComponent,
    WebapiComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    /* Changes start here. */
    // Import the following Angular materials. 
    MatButtonModule,
    MatToolbarModule,
    MatListModule,
    MatTableModule,
    // Import the HTTP client. 
    HttpClientModule,

    // Initiate the MSAL library with the MSAL configuration object
    MsalModule.forRoot(new PublicClientApplication(msalConfig),
      {
        // The routing guard configuration. 
        interactionType: InteractionType.Redirect,
        authRequest: {
          scopes: protectedResources.todoListApi.scopes
        }
      },
      {
        // MSAL interceptor configuration.
        // The protected resource mapping maps your web API with the corresponding app scopes. If your code needs to call another web API, add the URI mapping here.
        interactionType: InteractionType.Redirect,
        protectedResourceMap: new Map([
          [protectedResources.todoListApi.endpoint, protectedResources.todoListApi.scopes]
        ])
      })
    /* Changes end here. */
  ],
  providers: [
    /* Changes start here. */
    {
      provide: HTTP_INTERCEPTORS,
      useClass: MsalInterceptor,
      multi: true
    },
    MsalGuard
    /* Changes end here. */
  ],
  bootstrap: [
    AppComponent,
    /* Changes start here. */
    MsalRedirectComponent
    /* Changes end here. */
  ]
})
export class AppModule { }

Konfigurowanie tras

W tej sekcji skonfiguruj trasy dla aplikacji Angular. Gdy użytkownik wybierze link na stronie, aby przejść w aplikacji jednostronicowej lub wprowadzi adres URL na pasku adresu, trasy mapuje adres URL na składnik Angular. Routing Angular może Uaktywnić interfejs używa funkcji MSAL Guard do sprawdzania, czy użytkownik jest zalogowany. Jeśli użytkownik nie jest zalogowany, biblioteka MSAL przeniesie użytkownika do Azure AD B2C w celu uwierzytelnienia.

W folderze src/app edytuj plik app-routing.module.ts wprowadź modyfikacje pokazane w poniższym fragmencie kodu. Zmiany są oflagowane za pomocą polecenia "Zmiany zaczynają się tutaj" i "Zmiany zakończą się tutaj".

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { MsalGuard } from '@azure/msal-angular';
import { HomeComponent } from './home/home.component';
import { ProfileComponent } from './profile/profile.component';
import { WebapiComponent } from './webapi/webapi.component';

const routes: Routes = [
  /* Changes start here. */
  {
    path: 'profile',
    component: ProfileComponent,
    // The profile component is protected with MSAL Guard.
    canActivate: [MsalGuard]
  },
  {
    path: 'webapi',
    component: WebapiComponent,
    // The profile component is protected with MSAL Guard.
    canActivate: [MsalGuard]
  },
  {
    // The home component allows anonymous access
    path: '',
    component: HomeComponent
  }
  /* Changes end here. */
];


@NgModule({
  /* Changes start here. */
  // Replace the following line with the next one
  //imports: [RouterModule.forRoot(routes)],
  imports: [RouterModule.forRoot(routes, {
    initialNavigation:'enabled'
  })],
  /* Changes end here. */
  exports: [RouterModule]
})
export class AppRoutingModule { }

Dodawanie przycisków logowania i wylogowywanie

W tej sekcji dodasz przyciski logowania i wyloguj się do składnika aplikacji . W folderze src/app otwórz plik app.component.ts i wprowadź następujące zmiany:

  1. Zaimportuj wymagane składniki.

  2. Zmień klasę, aby zaimplementować metodę OnInit. Metoda OnInit subskrybuje zdarzenie MsalBroadcastService msalBroadcastServiceinProgress$ . Użyj tego zdarzenia, aby poznać stan interakcji użytkownika, szczególnie w celu sprawdzenia, czy interakcje zostały ukończone.

    Przed interakcjami z obiektem konta biblioteki MSAL sprawdź, czy InteractionStatus właściwość zwraca InteractionStatus.Nonewartość . Zdarzenie subscribe wywołuje metodę w setLoginDisplay celu sprawdzenia, czy użytkownik jest uwierzytelniony.

  3. Dodaj zmienne klasy.

  4. Dodaj metodę uruchamianą login przez przepływ autoryzacji.

  5. Dodaj metodę, która wy logout loguje użytkownika.

  6. Dodaj metodę setLoginDisplay , która sprawdza, czy użytkownik jest uwierzytelniony.

  7. Dodaj metodę ngOnDestroy , aby wyczyścić inProgress$ zdarzenie subskrypcji.

Po wprowadzeniu zmian kod powinien wyglądać podobnie do następującego fragmentu kodu:

import { Component, OnInit, Inject } from '@angular/core';
import { MsalService, MsalBroadcastService, MSAL_GUARD_CONFIG, MsalGuardConfiguration } from '@azure/msal-angular';
import { InteractionStatus, RedirectRequest } from '@azure/msal-browser';
import { Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

/* Changes start here. */
export class AppComponent implements OnInit{
  title = 'msal-angular-tutorial';
  loginDisplay = false;
  private readonly _destroying$ = new Subject<void>();

  constructor(@Inject(MSAL_GUARD_CONFIG) private msalGuardConfig: MsalGuardConfiguration, private broadcastService: MsalBroadcastService, private authService: MsalService) { }

  ngOnInit() {

    this.broadcastService.inProgress$
    .pipe(
      filter((status: InteractionStatus) => status === InteractionStatus.None),
      takeUntil(this._destroying$)
    )
    .subscribe(() => {
      this.setLoginDisplay();
    })
  }

  login() {
    if (this.msalGuardConfig.authRequest){
      this.authService.loginRedirect({...this.msalGuardConfig.authRequest} as RedirectRequest);
    } else {
      this.authService.loginRedirect();
    }
  }

  logout() { 
    this.authService.logoutRedirect({
      postLogoutRedirectUri: 'http://localhost:4200'
    });
  }

  setLoginDisplay() {
    this.loginDisplay = this.authService.instance.getAllAccounts().length > 0;
  }

  ngOnDestroy(): void {
    this._destroying$.next(undefined);
    this._destroying$.complete();
  }
  /* Changes end here. */
}

W folderze src/app edytuj app.component.html i wprowadź następujące zmiany:

  1. Dodaj link do składników profilu i internetowego interfejsu API.
  2. Dodaj przycisk logowania z atrybutem zdarzenia kliknięcia ustawionym na metodę login() . Ten przycisk jest wyświetlany tylko wtedy, gdy zmienna loginDisplay klasy to false.
  3. Dodaj przycisk wylogowywanie za pomocą atrybutu zdarzenia kliknięcia ustawionego na metodę logout() . Ten przycisk jest wyświetlany tylko wtedy, gdy zmienna loginDisplay klasy to true.
  4. Dodaj element gniazda routera .

Po wprowadzeniu zmian kod powinien wyglądać podobnie do następującego fragmentu kodu:

<mat-toolbar color="primary">
  <a class="title" href="/">{{ title }}</a>

  <div class="toolbar-spacer"></div>

  <a mat-button [routerLink]="['profile']">Profile</a>
  <a mat-button [routerLink]="['webapi']">Web API</a>

  <button mat-raised-button *ngIf="!loginDisplay" (click)="login()">Login</button>
  <button mat-raised-button *ngIf="loginDisplay" (click)="logout()">Logout</button>

</mat-toolbar>
<div class="container">
  <router-outlet></router-outlet>
</div>

Opcjonalnie zaktualizuj plik app.component.css przy użyciu następującego fragmentu kodu CSS:

.toolbar-spacer {
    flex: 1 1 auto;
  }

  a.title {
    color: white;
  }

Obsługa przekierowań aplikacji

Jeśli używasz przekierowań z biblioteką MSAL, musisz dodać dyrektywę przekierowania aplikacji do index.html. W folderze src edytuj index.html , jak pokazano w poniższym fragmencie kodu:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>MsalAngularTutorial</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
  <!-- Changes start here -->
  <app-redirect></app-redirect>
  <!-- Changes end here -->
</body>
</html>

Ustawianie css aplikacji (opcjonalnie)

W folderze /src zaktualizuj plik styles.css następującym fragmentem kodu CSS:

@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';

html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
.container { margin: 1%; }

Porada

Na tym etapie możesz uruchomić aplikację i przetestować środowisko logowania. Aby uruchomić aplikację, zobacz sekcję Uruchamianie aplikacji Angular.

Sprawdzanie, czy użytkownik jest uwierzytelniony

Plik home.component pokazuje, jak sprawdzić, czy użytkownik jest uwierzytelniony. W folderze src/app/home zaktualizuj plik home.component.ts przy użyciu następującego fragmentu kodu.

Kod:

  1. Subskrybuje msalbroadcastService msalBroadcastServicemsalSubject$ i inProgress$ obserwowane zdarzenia.
  2. Gwarantuje, że msalSubject$ zdarzenie zapisuje wynik uwierzytelniania w konsoli przeglądarki.
  3. Gwarantuje, że inProgress$ zdarzenie sprawdza, czy użytkownik jest uwierzytelniony. Metoda getAllAccounts() zwraca co najmniej jeden obiekt.
import { Component, OnInit } from '@angular/core';
import { MsalBroadcastService, MsalService } from '@azure/msal-angular';
import { EventMessage, EventType, InteractionStatus } from '@azure/msal-browser';
import { filter } from 'rxjs/operators';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  loginDisplay = false;

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

  ngOnInit(): void {
    this.msalBroadcastService.msalSubject$
      .pipe(
        filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS),
      )
      .subscribe((result: EventMessage) => {
        console.log(result);
      });

    this.msalBroadcastService.inProgress$
      .pipe(
        filter((status: InteractionStatus) => status === InteractionStatus.None)
      )
      .subscribe(() => {
        this.setLoginDisplay();
      })
  }

  setLoginDisplay() {
    this.loginDisplay = this.authService.instance.getAllAccounts().length > 0;
  }
}

W folderze src/app/home zaktualizuj home.component.html następującym fragmentem kodu HTML. Dyrektywa *ngIf sprawdza zmienną klasy, loginDisplay aby pokazać lub ukryć komunikaty powitalne.

<div *ngIf="!loginDisplay">
    <p>Please sign-in to see your profile information.</p>
</div>

<div *ngIf="loginDisplay">
    <p>Login successful!</p>
    <p>Request your profile information by clicking Profile above.</p>
</div>

Odczytywanie oświadczeń tokenu identyfikatora

Plik profile.component pokazuje, jak uzyskać dostęp do oświadczeń tokenu identyfikatora użytkownika. W folderze src/app/profile zaktualizuj plik profile.component.ts przy użyciu następującego fragmentu kodu.

Kod:

  1. Importuje wymagane składniki.
  2. Subskrybuj zdarzenie MSalBroadcastServiceinProgress$ . Zdarzenie ładuje konto i odczytuje oświadczenia tokenu identyfikatora.
  3. Gwarantuje, że checkAndSetActiveAccount metoda sprawdza i ustawia aktywne konto. Ta akcja jest powszechna, gdy aplikacja wchodzi w interakcję z wieloma przepływami użytkowników Azure AD B2C lub zasadami niestandardowymi.
  4. Zapewnia, że getClaims metoda pobiera oświadczenia tokenu identyfikatora z aktywnego obiektu konta MSAL. Następnie metoda dodaje oświadczenia do tablicy dataSource . Tablica jest renderowana dla użytkownika z powiązaniem szablonu składnika.
import { Component, OnInit } from '@angular/core';
import { MsalBroadcastService, MsalService } from '@azure/msal-angular';
import { EventMessage, EventType, InteractionStatus } from '@azure/msal-browser';
import { Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})

export class ProfileComponent implements OnInit {
  displayedColumns: string[] = ['claim', 'value'];
  dataSource: Claim[] = [];
  private readonly _destroying$ = new Subject<void>();
  
  constructor(private authService: MsalService, private msalBroadcastService: MsalBroadcastService) { }

  ngOnInit(): void {

    this.msalBroadcastService.inProgress$
      .pipe(
        filter((status: InteractionStatus) =>  status === InteractionStatus.None || status === InteractionStatus.HandleRedirect),
        takeUntil(this._destroying$)
      )
      .subscribe(() => {
        this.checkAndSetActiveAccount();
        this.getClaims(this.authService.instance.getActiveAccount()?.idTokenClaims)
      })
  }

  checkAndSetActiveAccount() {

    let activeAccount = this.authService.instance.getActiveAccount();

    if (!activeAccount && this.authService.instance.getAllAccounts().length > 0) {
      let accounts = this.authService.instance.getAllAccounts();
      this.authService.instance.setActiveAccount(accounts[0]);
    }
  }

  getClaims(claims: any) {

    let list: Claim[]  =  new Array<Claim>();

    Object.keys(claims).forEach(function(k, v){
      
      let c = new Claim()
      c.id = v;
      c.claim = k;
      c.value =  claims ? claims[k]: null;
      list.push(c);
    });
    this.dataSource = list;

  }

  ngOnDestroy(): void {
    this._destroying$.next(undefined);
    this._destroying$.complete();
  }
}

export class Claim {
  id: number;
  claim: string;
  value: string;
}

W folderze src/app/profile zaktualizuj profile.component.html następującym fragmentem kodu HTML:

<h1>ID token claims:</h1>

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">

  <!-- Claim Column -->
  <ng-container matColumnDef="claim">
    <th mat-header-cell *matHeaderCellDef> Claim </th>
    <td mat-cell *matCellDef="let element"> {{element.claim}} </td>
  </ng-container>

  <!-- Value Column -->
  <ng-container matColumnDef="value">
    <th mat-header-cell *matHeaderCellDef> Value </th>
    <td mat-cell *matCellDef="let element"> {{element.value}} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

Wywoływanie interfejsu API sieci Web

Aby wywołać internetowy interfejs API autoryzacji opartej na tokenach, aplikacja musi mieć prawidłowy token dostępu. Dostawca MsalInterceptor automatycznie uzyskuje tokeny dla żądań wychodzących, które używają klasy Angular HttpClient do znanych chronionych zasobów.

Ważne

Metoda inicjowania biblioteki MSAL (w app.module.ts klasie) mapuje chronione zasoby, takie jak internetowe interfejsy API, z wymaganymi zakresami aplikacji przy użyciu protectedResourceMap obiektu. Jeśli kod musi wywołać inny internetowy interfejs API, dodaj identyfikator URI internetowego interfejsu API i metodę HTTP internetowego interfejsu API z odpowiednimi zakresami do protectedResourceMap obiektu. Aby uzyskać więcej informacji, zobacz Chroniona mapa zasobów.

Gdy obiekt HttpClient wywołuje internetowy interfejs API, dostawca msalInterceptor wykonuje następujące czynności:

  1. Uzyskuje token dostępu z wymaganymi uprawnieniami (zakresami) dla internetowego punktu końcowego interfejsu API.

  2. Przekazuje token dostępu jako token elementu nośnego w nagłówku autoryzacji żądania HTTP przy użyciu następującego formatu:

    Authorization: Bearer <access-token>
    

Plik webapi.component przedstawia sposób wywoływania internetowego interfejsu API. W folderze src/app/webapi zaktualizuj plik webapi.component.ts przy użyciu następującego fragmentu kodu.

Kod:

  1. Używa klasy Angular HttpClient do wywoływania internetowego interfejsu API.
  2. Odczytuje auth-config element klasy protectedResources.todoListApi.endpoint . Ten element określa identyfikator URI internetowego interfejsu API. Na podstawie identyfikatora URI internetowego interfejsu API przechwytywanie biblioteki MSAL uzyskuje token dostępu z odpowiednimi zakresami.
  3. Pobiera profil z internetowego interfejsu API i ustawia zmienną profile klasy.
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { protectedResources } from '../auth-config';

type ProfileType = {
  name?: string
};

@Component({
  selector: 'app-webapi',
  templateUrl: './webapi.component.html',
  styleUrls: ['./webapi.component.css']
})
export class WebapiComponent implements OnInit {
  todoListEndpoint: string = protectedResources.todoListApi.endpoint;
  profile!: ProfileType;

  constructor(
    private http: HttpClient
  ) { }

  ngOnInit() {
    this.getProfile();
  }

  getProfile() {
    this.http.get(this.todoListEndpoint)
      .subscribe(profile => {
        this.profile = profile;
      });
  }
}

W folderze src/app/webapi zaktualizuj webapi.component.html następującym fragmentem kodu HTML. Szablon składnika renderuje nazwę zwracaną przez internetowy interfejs API. W dolnej części strony szablon renderuje adres internetowego interfejsu API.

<h1>The web API returns:</h1>
<div>
    <p><strong>Name: </strong> {{profile?.name}}</p>
</div>

<div class="footer-text">
    Web API: {{todoListEndpoint}}
</div>

Opcjonalnie zaktualizuj plik webapi.component.css następującym fragmentem kodu CSS:

.footer-text {
    position: absolute;
    bottom: 50px;
    color: gray;
}

Uruchamianie aplikacji Angular

Uruchom następujące polecenie:

npm start

W oknie konsoli jest wyświetlana liczba portów, na których jest hostowana aplikacja.

Listening on port 4200...

Porada

Alternatywnie, aby uruchomić npm start polecenie, użyj debugera Visual Studio Code. Debuger pomaga przyspieszyć edytowanie, kompilowanie i debugowanie pętli.

Przejdź do http://localhost:4200 witryny w przeglądarce, aby wyświetlić aplikację.

Następne kroki