【第08回】Deep Dive マルチテナントSaaS on AWS - 第6章振返り
はじめに
本記事では、「マルチテナント SaaS アーキテクチャの構築 ― 原則、ベストプラクティス、AWS アーキテクチャパターンの第 6 章「テナントの認証とルーティング」の内容を振り返り、自分なりに要点を整理していきます。
6 章では、アプリケーションにアクセスするための認証及びルーティングの仕組みについて考えていきます。
正面玄関から入る
まずは、アプリケーションへアクセスする方法の検討からスタートします。各テナントにアプリケーションへのアクセスする方法としては主に以下の選択肢が挙げられます。
- 各テナント情報をアプリケーションドメインドメインに含め、各テナントは対応するドメインにアクセスする
- 共通するアプリケーションドメインに全てのテナントがアクセスする
これらのうちどの方法を選択するかによって、SaaS アーキテクチャの他の側面にも様々な影響をもたらします。それらの影響について詳しく確認していきます。
テナントドメイン経由でのアクセス
まずは、テナントを識別する情報が含まれドメイン経由でアクセスする方法について考えていきます。
このアプローチでは、各テナントからの全てのリクエストは、上図でテナントマッピングと表現されるエンティテを経由します。テナントエンティティでは、各テナントのドメインを適切なバックエンドサービスにルーティングするための一連の技術、インフラストラクチャ、サービスを意味しています。
このアプローチが利用される主なユースケースは、テナントごとに個別のアイデンティティプロバイダが割り当てられていたり、アプリケーションプレーンがテナントごとにサイロ化していたりする場合です。テナントマッピングはドメインから適切な宛先にリクエストをルーティングすることが出来ます。
アプリケーションドメインへのテナント情報の具体的な含め方は大きく 2 つ考えられます。1 つは、サブドメインにテナント情報を含める方式です(tenant1.example.com, tenant2.example.com といった具合)。この方式は大きな複雑性やオーバーヘッドを伴わずに実現する可能性が高いです。もう 1 つは、テナントごとに独立したバニティドメインを割り当てることです。この方式は、ブランディング等の目的でテナントが独自のドメインを使用したい場合に有効といえます。
単一ドメイン経由でのアクセス
次に考えるのは、すべてのテナントに対して 1 つのドメインを使用する方式です。これは特に B2C の SaaS プロバイダで用いられるアクセス方式です。
この方式では上図のように、単一のアイデンティティプロバイによって、全てのテナントユーザが認証されます。アイデンティティプロバイダがグループ化構造をサポートしている場合、テナントごとに個別の認証ポリシーを適用することが出来ます。ただしその際、適用すべきポリシーをユーザ情報から識別する方法を検討する必要があります。具体例の一つとしては、下図のように個々のユーザ情報とテナントとのマッピングをテナント管理サービス上で保管し、このマッピング情報に応じて、認証時にテナントごとの認証ポリシーを適用する、といった具合です。
マルチテナントの認証フロー
ここではひとまず、認証リクエストが適切なアイデンティティプロバイダにルーティングされる方法が確立されたと仮定し、次は認証プロセスの残りのプロセス、つまりはテナントユーザを認証し、SaaS アイデンティティをレスポンスすること、について考えていきます。
認証フローの例
下図はここで詳しく見ていく認証フローの概念図です。
ここでは、テナントごとにサブドメインを割り当てていると仮定します。未認証のテナントユーザがサブドメインにアクセスすると(①)、Web アプリケーションはユーザをアプリケーションのログイン画面に誘導し、ユーザはそこで認証情報を入力します。次にテナント管理サービスにアクセスして、テナントに割り当てられているアイデンティティプロバイダ構造を決定します(②)。テナント管理サービスは、サブドメインからテナントを識別し、関連するアイデンティティプロバイの情報を Web アプリケーションにレスポンスします(③)。ここからは OAuth フローの典型的な認証手順に沿って、まずはテナントに対応するアイデンティティプロバイダを呼び出し、テナントユーザの認証情報を渡します(④)。アイデンティティプロバイダはコードを返し(⑤)、そのコードを JWT と交換します(⑥)。最後に、テナントコンテキストを含む JWT を使用して、マイクロサービスの呼び出しを行います(⑦)。
フェデレーション認証
マルチテナントの認証及び認可は、テナントコンテキストを含む JTW の利用に大きく依存しています。そのため、サードパーティー含む様々な種類のアイデンティティプロバイダでフェデレーション認証をサポートしようとする場合、テナントコンテキストを埋め込み、認証時にそれを参照する方式がどの様に実現できるかを考えることが重要です。
認証済みテナントのルーティング
認証リクエストが成功したと仮定して、次に、テナントコンテキストがバックエンドサービスの呼び出しにどの様な影響を与えるかについて考えいます。具体的には、テナントコンテキストがリクエストのルーティングに与える影響について考えます。
例えば下図のように、サイロ化されたリソースが混在するような複雑なマルチテナントアーキテクチャでは、リクエストを適切なテナントリソースにルーティングする方法を検討する必要があります。
具体的に採用できるアプローチは、使用している技術スタックやデプロイモデルによって様々です。次に様々な技術スタックによるルーティングの AWS 上での実装例について考えていきます。
サーバレスのテナントルーティング
下図は、AWS のサーバレスサービスで構成された、マイクロサービスがサイロ化された Sa さ S 環境の概念図です。
ここではプール化されたリソース用と、テナント個別のサイロ化されたリソース用に API Gateway をプロビジョニングするモデルを選択しています。
このモデルでは、各リクエストが処理される際に、テナントコンテキスを使用して適切なゲートウェイ URL にルーティングする必要があります。方法の 1 つとして考えられるのは、テナントがサブドメインによって識別されている場合、リクエストヘッダ内のオリジンを参照して適切なゲートウェイ URL をテナント管理サービスに照会するといった方法です。一方で、この方法はリクエストの度にテナント管理サービスへの照会になりパフォーマンスの問題を引き起こさないよう、キャッシュ戦略も併用する等が必要になります。
コンテナのテナントルーティング
次は、Kubernetes で構築された SaaS 環境でのテナントルーティングの実現方法を考えます。
下図では、サービスメッシュを使用した実現例です。
この例では、リクエストはネットワークロードバランサを通過し(①②)、Istio Ingress ゲートウェイに到達します。このゲートウェイで、アイデンティティプロバイダやバックエンドサービスへのルーティングに必要な全てのポリシーを管理・運用します。
未認証のリクエストを受信した場合(③)、Envoy リバースプロキシ(④)によって送信元のサブドメインに対応した Namespace 上で稼働する OIDC プロキシにリクエストがルーティングされます(④)。OIDC プロキシによってテナントに対応するアイデンティティプロバイダに認認リクエストエが転送されます。
認証されたリクエストはゲートウェイによって、個別の Namespace で稼働しているバックエンドサービスにルーティングされます(⑤)。
この方式は、リクエスト時にテナント管理サービスへの照会等を通してルーティング先を決定するという責任が廃され、アプリケーションロジックがシンプルに保たれるとうい面で前述の方式よりも洗練されているといえます。
Discussion