[Angular] ユーザ認証をAzure ADやMicrosoftアカウントに任せる

**2021/3/24追記**
oidc-clientとngrxを使用している[ng-oidc-client](https://www.npmjs.com/package/ng-oidc-client)が一番良さそうです。

~~ただ、Azureは特別な仕様のようで、これをそのまま使うことはできません。
最初の認証には使えます。その後、リソースサーバへ接続するためのアクセストークンに問題があります。Azureの場合、リソースごとにスコープを指定してアクセストークンを取得する必要があります。そのため、アクセストークンの管理は自前でやらないといけないです。~~ 取得されているアクセストークンがv1.0のためかもしれません。どうすればv2.0になるのか調査中です。

**2021/3/19追記**

[oidc-client](https://www.npmjs.com/package/oidc-client)のほうがわかりやすいかもしれません。あるいは[angular-oauth2-oidc](https://www.npmjs.com/package/angular-oauth2-oidc)もよいかもしれません。

**2021/3/18追記**

@azure/msal-angularより[angular-auth-oidc-client](https://www.npmjs.com/package/angular-auth-oidc-client)を使うほうがシンプルで良さそうです。


**2021/2/25追記**
@azure/msal-angular の新しい版 2.x が出ていました。
この記事の内容は、古い 1.x 時代のものです。

参考に 1.x から 2.x への移行ガイドを貼っておきます。
https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/v2-docs/1.x-2.x-upgrade-guide.md

# はじめに

Angularアプリから、Azure ADやMicrosoftアカウントで保護されたリソースへアクセスします。

そのため、最初にユーザ認証します。

# 準備

## (1) Azure ADにアプリケーションを登録

Azure ADにアプリケーションを登録します。

1. [Azure ADのApp registrations](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps) を開きます。
2. **New registration** をクリックします。
3. 以下の項目を入力して、**Register** をクリックします。

| 入力項目 | 内容 |
|:--|:--
| Name | アプリケーションの名前です。お好みの名前をつけます。  |
| Supported account type | アプリケーションを使用できるユーザアカウント種別を選択します。任意のAzure ADテナントとMicrosoftアカウントから使用できるようにする場合は **Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)** を選択します。  |
| Redirect URI  | 入力しないでOKです（後で設定します）。  |

作成できると **Application (client) ID** が表示されるので、控えておきます。

## (2) Azure ADアプリケーションにプラットフォームを登録

作成したAzure ADアプリケーションにプラットフォームを登録します。

1. **Manage**の下にある**Authentication**をクリックします。
2. **Add a platform**をクリックします。
3. **Single-page application**をクリックします。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/080b9803-3c4d-0820-c8f0-55002dca7e93.png)
4. 以下の項目を入力して**Configure**をクリックします。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/b614a241-cf1e-fea3-2754-355852f19432.png)

| 入力項目 | 内容 |
|:--|:--|
| Redirect URIs | 開発時なので **http://localhost:4200/** にします。  |
| Front-channel logout URL  | 空でOKです。   |
| Access tokens  | チェックします。  |
| ID tokens  | チェックします。  |


# 手順(1) : Angularアプリケーションを用意

既存のものを使うか、新規に作成します。
ルーティングを有効にしておきます。

# 手順(2) : パッケージを追加

パッケージを2つ追加します。

```bash
npm install msal --save
npm install @azure/msal-angular --save
```

@azure/msal-angular はAngular 9までの対応となっていますが、一応Angular 11でも動いています。
（早くアップデートしないかな。。。）

# 手順(3) : 環境設定

開発/本番で設定を入れ替えられるように、`src/environments/environment.ts` ファイルへ追記します。

```ts
import { Configuration } from 'msal';

export const msalConfiguration: Configuration = {
  auth: {
    clientId: 'Azure ADアプリケーションのApplication ID',
    authority: 'https://login.microsoftonline.com/common',
    redirectUri: 'http://localhost:4200/',
  },
  cache: {
    cacheLocation: 'localStorage',
  },
};
```

Client IDは、Azure ADアプリケーションの概要画面に表示されています。
Authorityは、アプリケーション作成時に選んだ　Supported account type によって変わります[（Step 3の真ん中あたりに書いてあります）](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-javascript#register-and-download-your-quickstart-application)。


| Supported account type | authority |
|:--|:--|
| Single tenant  |  https://login.microsoftonline.com/テナントIDまたはテナント名 |
| Multitenant  | https://login.microsoftonline.com/organizations  |
| Multitenant and MSA  | https://login.microsoftonline.com/common  |
| MSA | https://login.microsoftonline.com/consumers |

# 手順(4) : MSALモジュールの読み込み

`src/app/app.module.ts` ファイルを編集します。

MSALモジュールの設定です。

```ts
import { MsalAngularConfiguration } from '@azure/msal-angular';

const msalAngularConfig: MsalAngularConfiguration = {
  popUp: false,
};
```

`@NgModule`の`imports`と`providers`に追記します。

```ts
import { MsalInterceptor, MsalModule } from '@azure/msal-angular';
import { msalConfiguration } from '../environments/environment';

@NgModule({
  imports: [
    MsalModule.forRoot(msalConfiguration, msalAngularConfig),
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: MsalInterceptor, multi: true },
  ]
})
```

# 手順(5) : ルートガードを設定

`src/app/app-routing.module.ts` ファイルを編集し、保護したいURLにルートガードを設定します。

```ts
import { MsalGuard } from '@azure/msal-angular';

const routes: Routes = [
  {
    path: '',
    component: TopPageComponent,
    pathMatch: 'full',
    canActivate: [MsalGuard],
  },
];
```

ここに書いてある`TopPageComponent`は、また別途作成しておいたものです。


# 実行

いつものように `npm run start` してサーバを起動し、http://localhost:4200/ へアクセスします。
https://login.microsoftonline.com へリダイレクトされます。
ログインすると、http://localhost:4200/ へ戻ってきて、ルーティングに設定した通りのコンポーネントが表示されます。


# ソース全体

[Github](https://github.com/sengokyu/Ex.AngularAzureMSAL) にソース全体を置いてます。