チュートリアル: Angular SPA で認証フローを処理する
このチュートリアルは、Angular 単一ページ アプリ (SPA) の構築と認証の準備について説明するシリーズのパート 3 です。 このシリーズのパート 2 では、Angular SPA を作成し、外部テナントによる認証用に準備しました。 このチュートリアルでは、Microsoft Authentication Library (MSAL) コンポーネントを追加することで、アプリの認証フローを処理する方法について学習します。
このチュートリアルでは、
- アプリケーションに認証フローを追加する
- MSAL コンポーネントをインポートする
- アプリケーションのホーム コンポーネントと保護されたコンポーネントにルートを追加します。
前提条件
認証構成ファイル auth-config.ts を作成する
src/app/ フォルダーに auth-config.ts という名前の新しいファイルを作成し、次のコード スニペットを追加します。 このファイルには認証パラメーターが含まれます。 これらのパラメーターは、Angular と MSAL Angular の構成を初期化するときに使用されます。
/** * This file contains authentication parameters. Contents of this file * is roughly the same across other MSAL.js libraries. These parameters * are used to initialize Angular and MSAL Angular configurations in * in app.module.ts file. */ import { LogLevel, Configuration, BrowserCacheLocation, } from '@azure/msal-browser'; /** * Configuration object to be passed to MSAL instance on creation. * For a full list of MSAL.js configuration parameters, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md */ export const msalConfig: Configuration = { auth: { clientId: 'Enter_the_Application_Id_Here', // This is the ONLY mandatory field that you need to supply. authority: 'https://Enter_the_Tenant_Subdomain_Here.ciamlogin.com/', // Replace the placeholder with your tenant subdomain redirectUri: '/', // Points to window.location.origin by default. You must register this URI on Azure portal/App Registration. postLogoutRedirectUri: '/', // Points to window.location.origin by default. }, cache: { cacheLocation: BrowserCacheLocation.LocalStorage, // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO between tabs. }, system: { loggerOptions: { loggerCallback(logLevel: LogLevel, message: string) { console.log(message); }, logLevel: LogLevel.Verbose, piiLoggingEnabled: false, }, }, }; /** * Scopes you add here will be prompted for user consent during sign-in. * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request. * For more information about OIDC scopes, visit: * https://learn.microsoft.com/entra/identity-platform/permissions-consent-overview#openid-connect-scopes */ export const loginRequest = { scopes: [], };
次の値を Microsoft Entra 管理センターから取得した値に置き換えます。
Enter_the_Application_Id_Here
の値を見つけ、Microsoft Entra 管理センターで登録したアプリのアプリケーション ID (clientId) に置き換えます。- [権限] で
Enter_the_Tenant_Subdomain_Here
を見つけ、それをテナントのサブドメインに置き換えます。 たとえば、テナントのプライマリ ドメインがcontoso.onmicrosoft.com
の場合は、contoso
を使用します。 テナント名がない場合は、テナントの詳細を読み取る方法を確認してください。
ファイルを保存します。
カスタム URL ドメインを使用する (省略可能)
カスタム ドメインを使用して、認証 URL を完全にブランド化します。 ユーザーの視点から見ると、認証プロセスの間、ユーザーは ciamlogin.com ドメイン名にリダイレクトされず、あなたのドメインにとどまります。
カスタム ドメインを使用するには、以下の手順を実行します。
「外部テナント内のアプリに対するカスタム URL ドメインの有効化」の手順を使用し、外部テナントに対してカスタム URL ドメインを有効にします。
authConfig.js ファイルで、
auth
オブジェクトを見つけて、次のようにします。authority
プロパティの値を https://Enter_the_Custom_Domain_Here/Enter_the_Tenant_ID_Here に更新します。Enter_the_Custom_Domain_Here
を実際のカスタム URL ドメインに、Enter_the_Tenant_ID_Here
を実際のテナント ID に置き換えます。 テナント ID がわからない場合は、テナントの詳細を読み取る方法を確認してください。- [Enter_the_Custom_Domain_Here] という値を持つ
knownAuthorities
プロパティを追加します。
たとえば、カスタム URL ドメインが login.contoso.com で、テナント ID が aaaabbbb-0000-cccc-1111-dddd2222eeee である場合、authConfig.js ファイルに変更を加えた結果の内容は以下のようになります。
//...
const msalConfig = {
auth: {
authority: process.env.AUTHORITY || 'https://login.contoso.com/aaaabbbb-0000-cccc-1111-dddd2222eeee',
knownAuthorities: ["login.contoso.com"],
//Other properties
},
//...
};
MSAL コンポーネントをインポートする
src/app/app.module.ts を開き、次のコード スニペットを追加します。
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; import { MatToolbarModule } from "@angular/material/toolbar"; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatTableModule } from '@angular/material/table'; import { MatMenuModule } from '@angular/material/menu'; import { MatDialogModule } from '@angular/material/dialog'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MatIconModule } from '@angular/material/icon'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HomeComponent } from './home/home.component'; import { GuardedComponent } from './guarded/guarded.component'; import { IPublicClientApplication, PublicClientApplication, InteractionType, } from '@azure/msal-browser'; import { MSAL_INSTANCE, MsalGuardConfiguration, MSAL_GUARD_CONFIG, MsalService, MsalBroadcastService, MsalGuard, MsalRedirectComponent, MsalInterceptor, MsalModule, } from '@azure/msal-angular'; import { msalConfig, loginRequest } from './auth-config'; /** * Here we pass the configuration parameters to create an MSAL instance. * For more info, visit: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/v2-docs/configuration.md */ export function MSALInstanceFactory(): IPublicClientApplication { return new PublicClientApplication(msalConfig); } /** * Set your default interaction type for MSALGuard here. If you have any * additional scopes you want the user to consent upon login, add them here as well. */ export function MsalGuardConfigurationFactory(): MsalGuardConfiguration { return { interactionType: InteractionType.Redirect, authRequest: loginRequest }; } @NgModule({ declarations: [ AppComponent, HomeComponent, GuardedComponent, ], imports: [ BrowserModule, BrowserAnimationsModule, AppRoutingModule, MatToolbarModule, MatButtonModule, MatCardModule, MatTableModule, MatMenuModule, HttpClientModule, BrowserAnimationsModule, MatDialogModule, MatIconModule, MsalModule, ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: MsalInterceptor, multi: true, }, { provide: MSAL_INSTANCE, useFactory: MSALInstanceFactory, }, { provide: MSAL_GUARD_CONFIG, useFactory: MsalGuardConfigurationFactory, }, MsalService, MsalBroadcastService, MsalGuard, ], bootstrap: [AppComponent, MsalRedirectComponent], }) export class AppModule { }
src/app/app-routing.module.ts を開き、ファイルの内容全体を次のスニペットに置き換えます。 これにより、
home
およびguarded
コンポーネントにルートが追加されます。import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { BrowserUtils } from '@azure/msal-browser'; import { MsalGuard } from '@azure/msal-angular'; import { HomeComponent } from './home/home.component'; import { GuardedComponent } from './guarded/guarded.component'; /** * MSAL Angular can protect routes in your application * using MsalGuard. For more info, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/v2-docs/initialization.md#secure-the-routes-in-your-application */ const routes: Routes = [ { path: 'guarded', component: GuardedComponent, canActivate: [ MsalGuard ] }, { path: '', component: HomeComponent, }, ]; @NgModule({ imports: [ RouterModule.forRoot(routes, { // Don't perform initial navigation in iframes or popups initialNavigation: !BrowserUtils.isInIframe() && !BrowserUtils.isInPopup() ? 'enabledNonBlocking' : 'disabled', // Set to enabledBlocking to use Angular Universal }), ], exports: [RouterModule], }) export class AppRoutingModule { }