Azure AD B2C のサンプルを使ってドメイン名によるアプリユーザーの登録制限を実装してみた

# シナリオとサンプル
例えば、Azure AD B2C で公開している Web アプリケーションへサインアップ（登録）できるユーザーを制限したいというケースを聞くことがある。
許可されていないメールアドレスを使ってアプリへサインアップしようとした場合に、下記のような画面がユーザーへ表示され、登録ができないようにしたいということだ。
この例では、fabrikam.com か fabricam.com のドメインに所属するアカウントのみが許可されていることを示している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/555b8e74-9f63-ebf4-47d9-2aff9644cff4.png)

技術的なカスタマイズで対応することになるが、Azure AD B2C の標準的な機能であるユーザーフローと API コネクタ を使うことで Azure ポータル 操作による簡単な設定が可能となる。

https://docs.microsoft.com/ja-jp/azure/active-directory-b2c/add-api-connector?pivots=b2c-user-flow

ドメイン名による制限のための実装サンプルは Github にあるものを利用し、その構成手順に従って、C# .NET Core のコードを Azure Functions へデプロイした。
Azure Functions の関数が、API コネクタの接続先サービスとなる。

https://github.com/Azure-Samples/active-directory-dotnet-external-identities-api-connector-azure-function-validate

> 同様の実装が可能な Node.js サンプルが公開されている。好みや環境に合わせて選択するとよいだろう。
https://github.com/Azure-Samples/active-directory-nodejs-external-identities-api-connector-azure-function-validate

サンプルコード内の設定箇所で、許可したいドメイン名の値を自由に指定することができる。

```C#:SignUpValication.cs(21-22) 
// Allowed domains
string[] allowedDomain = { "fabrikam.com", "fabricam.com" };
```

アプリユーザーの登録時に、ユーザーによって入力されたメールアドレスをログイン ID の値として Azure Functions で検証し、結果を Azure AD B2C へ HTTP のレスポンスとして返す仕組みが実装される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/4f412f2c-2ba3-c811-09b1-1c7a4df144ca.png)

# 実行環境
クラウドに必要な環境は、Azure サブスクリプション（Azure Functions 用）と Azure AD B2C テナントとなる。
ローカルにインストールした Visual Studio Code から Azure Functions を構成した。
Azure Functions 拡張機能 (Azure Functions for Visual Studio Code)や C# for Visual Studio Code は最新バーションを利用した。
その他にローカルへインストールしたツールのバージョンは以下の通り。

* Azure Functions Core Tools 4.0
* Microsoft .NET Core SDK 3.1

Github サンプルの README または 下記のドキュメントを参考にすると確実だ。

https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-develop-vs-code?tabs=csharp#prerequisites

# API コネクタ をユーザーサインアップ用のユーザーフローへ設定
Azure AD B2C で API コネクタを作成する。表示名の他に指定が必要な値となる **URL** と **認証の種類** について順次説明する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/f4bbde0b-5f26-679b-caa9-bac7c44b4275.png)

* URL

API 接続先サービスのエンドポイントとして、Azure Functions へデプロイした関数の URL を指定した。このサービスによってユーザー ID の検証が行われる。
この URL は、Visual Studio Code から取得できる点に留意しておくと良い。下記のように関数名を右クリックしてから URL コピーを選択し、API コネクタの構成画面で指定した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/23a15648-63c3-6fe8-6463-054080529055.png)

* 認証の種類

Basic を指定した。サンプル実行であれば Basic で問題ないと思われるが、資格情報保護の観点からはもう１つの選択肢である証明書を利用してセキュアにする方が望ましい。
Basic 認証の資格情報は、下記のローカル設定ファイルに指定する。（リモートリポジトリには置かないこと。）

```local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "BASIC_AUTH_USERNAME": "<USERNAME>",
    "BASIC_AUTH_PASSWORD": "<PASSWORD>"
  }
}
```

次に、サインアップ用ユーザーフローの設定の中で、構成した API コネクタを指定する。この設定によって、サインアップのユーザーエクスペリエンスが更新され、ユーザーを作成する前にログイン ID の検証が行われる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/bd88ae1e-9730-66e6-57bd-4cc18dc2043c.png)

# ユーザーフローの実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/ce566c25-8106-12b6-58dc-b2f31b806756.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/1af88f90-eafc-021b-c23b-2398b068cd2a.png)

API コネクタ設定後、Azure AD B2C へ登録済みアプリケーションを選択して、ユーザーフローを実行する。
今回は、公開チュートリアルに掲載されているもので、手軽に設定が可能な Web アプリケーションサンプル (https://jwt.ms) を使って実行した。
許可されたドメイン名を入力した場合は、アプリケーションの画面 (JWTの値が表示される応答画面) が表示され、許可されていないドメイン名を入力した場合は冒頭のエラー画面が表示される。

https://docs.microsoft.com/ja-jp/azure/active-directory-b2c/tutorial-register-applications?tabs=app-reg-ga

# まとめ
* ドメイン名によるアプリユーザーの登録制限の実装サンプルの紹介
* Azure AD B2C のユーザーフローと API コネクタを活用可能
* API コネクタの接続先サービスは Azure Functions の関数を利用

最後まで読んでいただきありがとうございました。

![AdobeStock_242080709.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/3a5a6bf1-80e7-42ed-1dbf-953a6c4069fe.jpeg)