Azure AD B2C テナントのマルチテナント SaaS での考慮点を整理し、カスタム属性を追加してみた

2023.12.28

いわさです。

先日から Azure 上での SaaS アーキテクチャーを学ぶために、Azure AD B2C で遊んでいます。
Amazon Cognito をよく使うので、その延長で使ってみているのですがかなり違うので戸惑っています。

前回は Azure AD B2C テナントを新規作成し、ユーザーフローを実行してサインアップ・サインインを行ったときの JWT クレームの内容を確認しました。

今回は Azure AD B2C をマルチテナント SaaS で利用する場合の考慮事項を整理した上で、カスタム属性の設定を行い、サインイン時にトークン側に設定されるところを確認してみました。

マルチテナント SaaS での認証基盤

SaaS における認証基盤は重要な部分です。
Azure アーキテクチャセンターの ID アーキテクチャに関する考慮事項では次のように独自の IdP 構築は避けるべきだと言及されています。結構強めに言われていますね...!

独自に IdP を構築するのは複雑でコストがかかるうえ、安全に構築するのは困難です。 独自 ID プロバイダーの構築は避けるべきです。 それは推奨されません。

現在は様々な IdP が存在しており、SaaS で認証基盤に求められるセキュリティやスケーラビリティなど高度な機能を考えると、まずは何かしらの IdP をアプリケーションに統合させる方向で考えたいところです。
上記ドキュメントの引用部分ほど強硬な非推奨を打ち出しはしないですが、IdP で実現出来ない場合に統合基盤を作り込むような流れが多いのではないかなと思います。

Azure AD B2C を使う場合

アプリケーション用に認証基盤の選択肢のひとつとして、Azure では Azure AD B2C が提供されています。
さらに Azure アーキテクチャセンターには Azure AD B2C を採用した場合のアプローチパターンが言及されています。

SaaS でマルチテナントを実現するにあたって、Azure AD B2C のテナントをどのように設計すればよいかという話です。
MFA やフェデレーションなどは Azure AD B2C が要件を満たしているかだけ確認すれば良いと思いますが、テナント分離方式とカスタム属性についてはほぼ必須で考える必要がありそうだなと思いました。

想定されるテナント数やポリシーなどから検討する

どのリソースでもこのあたりはトレードオフが発生するのですが、上記ドキュメントや Azure AD B2C の仕様・制限事項から、Azure AD B2C の場合は概ね以下のように考えることが出来ると思います。

  • Azure 利用料金
    • Azure AD B2C はアクティブユーザーごとの従量課金となるので Azure 利用料金だけで見ると AAD B2C テナントを分割しても共用してもどちらでも良い
  • クォータ厳しめ
    • テナント数の上限
    • AAD B2C テナントはサブスクリプションの紐付ける形になるが、1 サブスクリプション 20 テナントまでの上限があるので、それを超える運用の場合は複数サブスクリプションで分散管理させる必要が出てくる
    • 1 テナント内の上限
    • テナントあたり、最大 200リクエスト/秒の上限がある。さらにユーザーフローごとに必要なリクエスト数は変わる。サインインだと 4 なのでつまり秒間 50 人までサインイン出来る。足りるか?
    • パスワードポリシーなどをテナントごとにカスタマイズさせる必要がある場合はユーザーポリシーやカスタムポリシーを SaaS テナントごとに分けることも出来るが、テナントあたり 200 ポリシーまでの上限がある

大規模な同時実行数や多様なポリシーをカバーする場合は AAD B2C テナントの複数運用が必要になりそうですが、サブスクリプションもスケールさせる必要があるので運用面での労力や自動化の作り込みが必要になりそうです。
そこまで必要そうであれば、Auth0 などのサードパーティ IdP の検討余地も出てくると思います。

カスタム属性を使う

上記の Azure アーキテクチャセンターでは、カスタム属性にテナントコンテキストを含めることも推奨されています。
IdP を使う場合は基本的にトークンベースで認証情報を受け渡しすると思いますが、JWT にテナント ID などのカスタムクレームを追加し、アプリケーション側でどのテナントの処理かを判断出来るようにするのは基本的なアプローチだと思います。

認証は IdP に任せるとして、認可部分をどうするのかはまた検討する必要があります。
認可部分はテナントごとにユーザー側で設定変更出来るようにするケースも多いので、アプリケーション側や別のデータストアなど、認証部分に比べると独自管理するケースが多いのかなと思います。

カスタム属性をトークンに出力する

テナントをどの単位で分割するとしてもカスタム属性の出力は推奨事項だと思うので、今回はその部分を試してみました。
作成済みの Azure AD B2C テナントで次のメニューから属性の追加が可能です。

今回は Azure アーキテクチャセンターにて推奨されているように、テナント ID とロールっぽいものをカスタム属性として追加してみました。
属性の追加はテナント共通の設定となっています。

ユーザーフローでそれらを使うかどうかはユーザーフローごとに設定が必要です。
ユーザー属性ではサインアップ時に収集される属性を設定します。

デフォルトユーザフローで設定すると、ユーザーに入力してもらう形となります。
通常ユーザーが自分でテナント ID などを入力するケースは無いと思いますが、カスタム属性の更新には API コネクタやカスタムポリシーで自動化するなどが必要になると思います。それらはまた別のタイミングで実装することとし、今回はユーザー入力させます。

アプリケーション要求で指定したカスタム属性はトークンのカスタムクレームとして出力されるようになりますのでここは運用時も必要になると思います。

ちなみに、AAD B2C のユーザー情報から属性編集が出来るのですが、カスタム属性はこの画面から設定や参照が出来ません。なんと...!
API で操作する場合は Microsoft Graph API の利用が必要になります。

ユーザーフローを実行してみます。
サインアップ時にカスタム属性の入力欄が追加されました。

リダイレクト先で JWT クレームを確認してみると「extension_<カスタム属性名>」という名称で出力されていることが確認出来ました。

さいごに

本日は Azure AD B2C テナントのマルチテナント運用での考慮点を整理し、カスタム属性を追加してみました。

マルチテナントについては、概ね Amazon Cognito と似たような考え方で良さそうです。
クォーターを意識する必要があるので、導入時には要件に併せて Azure AD B2C を選定すべきかよく検討が必要ですね。ドキュメントに記載されている以上に上限緩和出来たりするのだろうか?

カスタム属性については今回は単純にユーザー入力させる形だったので単純に追加して動作確認しただけですが、属性を追加すると、自動設定に必要なカスタムポリシーや API コネクタがほぼ必須になるので、そのあたりのノウハウが必要になりますね。
このあたりはまたちょっと難易度が高い気がしますが、試して紹介したいと思います。