しばやん雑記

Azure Serverless とメイドさんが大好きなフリーランスのプログラマーのブログ

App Service Authentication で Azure AD と Microsoft Account を使ったログインを実装する

App Service Authentication は非常に便利でかなり頻繁に使っていますが、基本はシングルテナントの利用が多く、Microsoft Account を使ったログイン方法に関してはこれまで試したことが無かったのと、NuGet のログイン画面を見て実現方法に興味を持ったので試してみました。

ちなみに NuGet のログイン画面は以下のようなものです。Microsoft Account と組織アカウントの両方でログイン出来ますが、常にアカウントの選択が必要かつ利用可能なアカウントがあれば表示されています。

f:id:shiba-yan:20210814023104p:plain

この NuGet と同じログイン画面を App Service Authentication だけで実現していきます。

登録済みであれば確認無しでシームレスにサインイン出来て便利ですが、複数サインインしている場合は利用するアカウントを選ばせたいケースもあるかなと思います。

MSA も利用可能な Azure AD アプリケーションを作成

適当に作成した Web Appで App Service Authentication を有効化していくわけですが、Azure Portal の新しい Authentication を使って設定するようにします。新しい設定では v2.0 エンドポイントが使われて MSA と Azure AD の扱いが統合されているので簡単に登録できます。

Identity Provider として Microsoft を選んだ後に表示される Supported account types を Current tenant から Any Azure AD directory & personal Microsoft accounts に変更します。

f:id:shiba-yan:20210814024040p:plain

これ以外の手順は通常と同じなのでドキュメントの方を参照してください。ボタンを押していくだけで Azure AD アプリケーションの作成とシークレットの登録まで行ってくれます。

ここまでの手順で Azure AD テナントに所属するアカウントでのログインは行えるようになっていますが、最後に MSA でログイン可能にするために Issuer URL を変更します。Azure Portal で作ると常にテナントに紐づく Issuer URL が設定されるので修正する必要があります。

具体的には https://sts.windows.net/TENANT_ID/v2.0 となっている Issuer URL を以下のように https://login.microsoftonline.com/common/v2.0 に変更します。

f:id:shiba-yan:20210814183012p:plain

この Issuer URL の意味についてはドキュメントが良くまとまっています。要するに MSA と Azure AD の両方でログイン可能にするためには common を使う必要があります。

設定を保存した後に Web App にアクセスしてみると、見慣れた Azure AD アプリケーションのアクセス許可の確認画面が表示されます。MSA でログインはしているのですが、Azure AD テナントにも所属しているのでこちらが優先されているようです。

f:id:shiba-yan:20210814024110p:plain

現在のテナントに所属していない MSA や、別テナントでアプリケーションを作成した場合には MSA が優先されて利用されるので、その場合は MSA 側のアクセス許可の確認画面が表示されます。

ログイン時にアカウントを選択可能にする

ここまでで MSA と Azure AD でログイン可能になりましたが、まだ NuGet のようなアカウント選択の画面は表示されないので、ログイン時のパラメータを追加して対応します。

NuGet の場合は prompt=select_account がログイン時に追加されています。ドキュメントにも説明と他に設定可能な値が載っているので参照してください。

ログイン時に渡す追加パラメータは Azure Portal から設定は出来ないので、Azure CLI や ARM Explorer などを使って設定する必要があります。手軽なので ARM Explorer を使うのが良いと思います。

ARM 上は authsettingsV2 として扱われているので、その中にある Azure AD セクションに以下のように loginParameters を追加します。

f:id:shiba-yan:20210814024907p:plain

保存した後に Web App にアクセスすると、以下のように常にアカウントの選択画面と、利用可能なアカウントがある場合は表示されるようになります。これで NuGet と同じログイン画面を実現出来ました。

f:id:shiba-yan:20210814025719p:plain

個人的には利用可能なアカウントが下に表示されるのが気に入っているので、MSA と組織アカウントの両方対応が必要なサービスの場合には使ってみたいと思っています。

MSA のみ利用可能にするときの注意点

今回は Azure AD と MSA の両方に対応した Azure AD アプリケーションと Web App の設定を行いましたが、MSA のみ利用可能なアプリケーションを作る際には同じような修正が必要となるのでメモしておきます。

Azure AD アプリケーションの作成自体は App Service Authentication の設定時に Personal microsoft account only を選ぶだけでよいです。

f:id:shiba-yan:20210814030003p:plain

この状態で Web App にアクセスすると MSA でのログイン後に 401 エラーとなります。

f:id:shiba-yan:20210814030154p:plain

例によって Issuer URL がテナントに紐づいている形式になっているのが原因のようなので、正しくログインを行うためには MSA 専用の Issuer URL に変更する必要があります。

古い App Service Authentication のドキュメントにはこの辺の手順が載っています。

MSA のみを使う場合には、以下のどちらかを Issuer URL に設定する必要があります。consumers は名前の通りですが、GUID で始まる方は MSA のテナント ID のようです。

https://login.microsoftonline.com/consumers/v2.0
https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0

f:id:shiba-yan:20210814030501p:plain

Issuer URL を変更して設定を保存すれば、MSA のみでのログインも正常に動作するようになります。

Azure Portal から設定した場合のみ Issuer URL が自動設定されるので、ARM Template や Terraform を使う際には Issuer URL を間違えなければ問題ないはずです。v1 と v2 と同様に注意しておきたいです。