教程:创建 Angular 应用程序并将其准备用于身份验证
注册完成后,可以使用 Angular CLI(命令行接口)创建 Angular 项目。 本教程演示如何使用 Angular CLI 创建单页 Angular 应用程序,以及如何创建身份验证和授权所需的文件。
本教程的内容:
- 创建新 Angular 项目
- 配置应用程序的设置
- 向应用程序添加身份验证代码
先决条件
- 完成教程:注册应用程序中的先决条件和步骤。
- 安装 Agular CLI
- 安装 Node.js。
- Visual Studio Code
创建新 Angular 项目
若要从头开始构建 Angular 项目,请执行以下步骤:
打开终端窗口并运行以下命令以创建新的 Angular 项目:
ng new msal-angular-tutorial --routing=true --style=css --strict=false
该命令创建一个名为
msal-angular-tutorial
的新 Angular 项目,其中启用了路由、用于样式设置的 CSS 和禁用严格模式。更改为项目目录:
cd msal-angular-tutorial
安装应用依赖项:
npm install @azure/msal-browser @azure/msal-angular bootstrap
该命令
npm install @azure/msal-browser @azure/msal-angular bootstrap
安装 Azure MSAL 浏览器、Azure MSAL Angular 和 Bootstrap 包。打开
angular.json
并将 Bootstrap 的 CSS 路径添加到styles
数组:"styles": [ "src/styles.css", "node_modules/bootstrap/dist/css/bootstrap.min.css" ],
该代码将 Bootstrap CSS 添加到
angular.json
文件中的样式数组。生成主页和配置文件组件:
ng generate component home ng generate component profile
这些命令在 Angular 项目中生成 Home 和 Profile 组件。
从项目中删除不必要的文件和代码:
rm src/app/app.component.css rm src/app/app.component.spec.ts rm src/app/home/home.component.css rm src/app/home/home.component.spec.ts rm src/app/profile/profile.component.css rm src/app/profile/profile.component.spec.ts
这些命令从项目中删除不必要的文件和代码。
使用 Visual Studio Code 将
app.routes.ts
重命名为app-routing.module.ts
,并更新整个应用程序中app.routes.ts
的所有引用。使用 Visual Studio Code 将
app.config.ts
重命名为app.module.ts
,并更新整个应用程序中app.config.ts
的所有引用。
完成这些步骤后,项目结构应如下所示:
.
├── README.md
├── angular.json
├── package-lock.json
├── package.json
├── src
│ ├── app
│ │ ├── app-routing.module.ts
│ │ ├── app.component.html
│ │ ├── app.component.ts
│ │ ├── app.module.ts
│ │ ├── home
│ │ │ ├── home.component.html
│ │ │ └── home.component.ts
│ │ └── profile
│ │ ├── profile.component.html
│ │ └── profile.component.ts
│ ├── index.html
│ ├── main.ts
│ ├── polyfills.ts
│ └── styles.css
├── tsconfig.app.json
└── tsconfig.json
配置应用程序的设置
我们将使用应用注册期间记录的值来配置应用程序进行身份验证。 执行以下步骤:
打开
src/app/app.module.ts
文件并将内容替换为以下代码:// Required for Angular multi-browser support import { BrowserModule } from '@angular/platform-browser'; // Required for Angular import { NgModule } from '@angular/core'; // Required modules and components for this application import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { ProfileComponent } from './profile/profile.component'; import { HomeComponent } from './home/home.component'; // HTTP modules required by MSAL import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; // Required for MSAL import { IPublicClientApplication, PublicClientApplication, InteractionType, BrowserCacheLocation, LogLevel } from '@azure/msal-browser'; import { MsalGuard, MsalInterceptor, MsalBroadcastService, MsalInterceptorConfiguration, MsalModule, MsalService, MSAL_GUARD_CONFIG, MSAL_INSTANCE, MSAL_INTERCEPTOR_CONFIG, MsalGuardConfiguration, MsalRedirectComponent } from '@azure/msal-angular'; const isIE = window.navigator.userAgent.indexOf('MSIE ') > -1 || window.navigator.userAgent.indexOf('Trident/') > -1; export function MSALInstanceFactory(): IPublicClientApplication { return new PublicClientApplication({ auth: { // 'Application (client) ID' of app registration in the Microsoft Entra admin center - this value is a GUID clientId: "Enter_the_Application_Id_Here", // Full directory URL, in the form of https://login.partner.microsoftonline.cn/<tenant> authority: "https://login.partner.microsoftonline.cn/Enter_the_Tenant_Info_Here", // Must be the same redirectUri as what was provided in your app registration. redirectUri: "http://localhost:4200", }, cache: { cacheLocation: BrowserCacheLocation.LocalStorage, storeAuthStateInCookie: isIE } }); } // MSAL Guard is required to protect routes and require authentication before accessing protected routes export function MSALGuardConfigFactory(): MsalGuardConfiguration { return { interactionType: InteractionType.Redirect, authRequest: { scopes: ['user.read'] } }; } // Create an NgModule that contains the routes and MSAL configurations @NgModule({ declarations: [ AppComponent, HomeComponent, ProfileComponent ], imports: [ BrowserModule, AppRoutingModule, HttpClientModule, MsalModule ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: MsalInterceptor, multi: true }, { provide: MSAL_INSTANCE, useFactory: MSALInstanceFactory }, { provide: MSAL_GUARD_CONFIG, useFactory: MSALGuardConfigFactory }, { provide: MSAL_INTERCEPTOR_CONFIG, useFactory: MSALInterceptorConfigFactory }, MsalService, MsalGuard, MsalBroadcastService ], bootstrap: [AppComponent, MsalRedirectComponent] }) export class AppModule { }
该代码为用户身份验证和 API 保护设置 MSAL。 它会将应用配置为使用
MsalInterceptor
来保护 API 请求,MsalGuard
来保护路由,同时定义用于身份验证的关键组件和服务。 将以下值替换为 Microsoft Entra 管理中心的值。- 将
Enter_the_Application_Id_Here
替换为应用注册中的Application (client) ID
。 - 将
Enter_the_Tenant_Info_Here
替换为应用注册中的Directory (tenant) ID
。
- 将
保存文件。
向应用程序添加身份验证代码
若要使用 MSAL Angular 处理用户身份验证和会话管理,需要更新 src/app/app.component.ts
。
打开
src/app/app.component.ts
文件并将内容替换为以下代码:// Required for Angular import { Component, OnInit, Inject, OnDestroy } from '@angular/core'; // Required for MSAL import { MsalService, MsalBroadcastService, MSAL_GUARD_CONFIG, MsalGuardConfiguration } from '@azure/msal-angular'; import { EventMessage, EventType, InteractionStatus, RedirectRequest } from '@azure/msal-browser'; // Required for RJXS import { Subject } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent implements OnInit, OnDestroy { title = 'Angular - MSAL Example'; loginDisplay = false; tokenExpiration: string = ''; private readonly _destroying$ = new Subject<void>(); constructor( @Inject(MSAL_GUARD_CONFIG) private msalGuardConfig: MsalGuardConfiguration, private authService: MsalService, private msalBroadcastService: MsalBroadcastService ) { } // On initialization of the page, display the page elements based on the user state ngOnInit(): void { this.msalBroadcastService.inProgress$ .pipe( filter((status: InteractionStatus) => status === InteractionStatus.None), takeUntil(this._destroying$) ) .subscribe(() => { this.setLoginDisplay(); }); // Used for storing and displaying token expiration this.msalBroadcastService.msalSubject$.pipe(filter((msg: EventMessage) => msg.eventType === EventType.ACQUIRE_TOKEN_SUCCESS)).subscribe(msg => { this.tokenExpiration= (msg.payload as any).expiresOn; localStorage.setItem('tokenExpiration', this.tokenExpiration); }); } // If the user is logged in, present the user with a "logged in" experience setLoginDisplay() { this.loginDisplay = this.authService.instance.getAllAccounts().length > 0; } // Log the user in and redirect them if MSAL provides a redirect URI otherwise go to the default URI login() { if (this.msalGuardConfig.authRequest) { this.authService.loginRedirect({ ...this.msalGuardConfig.authRequest } as RedirectRequest); } else { this.authService.loginRedirect(); } } // Log the user out logout() { this.authService.logoutRedirect(); } ngOnDestroy(): void { this._destroying$.next(undefined); this._destroying$.complete(); } }
该代码将 MSAL 与 Angular 集成,以管理用户身份验证。 它会侦听登录状态更改、显示登录状态、处理令牌获取事件,并提供基于 Microsoft Entra 配置登录或注销的方法。
保存文件。