しばやん雑記

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

Azure AD B2C にカスタムドメインを設定して MSAL (C# / JavaScript) から使ってみた

恐らく Azure AD B2C を使っている人全員が待ち望んでいたカスタムドメイン対応ですが、Front Door と組み合わせる形にはなりますが Preview として公開されました。

単純に Front Door をリバースプロキシとして使うだけなのですが、割と現実的な落としどころな実装になった感があります。Front Door 分の課金は必要になりますが、こればかりは仕方ありません。

カスタムドメインの設定方法のドキュメントが公開されているので、これに従って実際に設定する方法と、設定後の Azure AD B2C を MSAL から使うところまで試してみました。

今回のカスタムドメイン対応と同じタイミングで、Azure AD B2C のログイン画面を iframe で使うための機能も Preview として公開されています。

SPA ではログイン時に必ず Azure AD B2C 側へのリダイレクトが必要でしたが、iframe を使うことで画面遷移なしにログインさせることが出来ます。UI のカスタマイズ性も向上するでしょう。

流石にこっちは試しませんが、暇なタイミングで UI に詳しい人と弄ってみたいと思います。

Active Directory にカスタムドメインを追加

とりあえずドキュメントに従って Active Directory に設定したいカスタムドメインを追加します。この辺りは Azure AD を使っていれば設定したことがある人は多そうです。

通常なら Azure AD B2C などにはサブドメインを割り当てると思いますが、Active Directory への追加時には Apex ドメインを最初に登録する必要があります。

Apex ドメインを追加すると検証プロセスが走るので、検証後にサブドメインを追加可能になります。

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

今回は使い道のないドメイン login.daruyanagi.com を使うので、daruyanagi.com から先に追加します。

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

使用するドメインが検証済みになれば Azure AD B2C 側の設定は完了です。この設定は Front Door で転送されてくるホスト名の許可リストになるようです。

Make primary を押したくなりましたが、いろいろと壊れそうな気がしたので止めておきました。

Front Door にカスタムドメインと B2C へのルーティングを追加

Azure AD B2C に使用するカスタムドメインを追加すれば、後は Front Door にカスタムドメインを割り当てて、B2C へのルーティングを追加するだけです。

特に説明も必要ない気はしますが、一応スクリーンショットを撮っておいたので簡単に書きます。Front Door で新規 Backend pool を作成して、Backend として b2clogin.com で終わるホスト名を設定します。

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

それ以外はデフォルトのままで問題ありません。Status が Enabled になっていることだけは確認します。

Backend pool では Health probes を無効化して保存します。単純にチェックの必要はありません。

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

後は Front Door の Frontend にカスタムドメインと証明書を設定して、ルーティングルールで先ほど作成した Backend pool を設定するだけで、Azure AD B2C のカスタムドメイン化が完了します。

実際には Azure AD に設定したカスタムドメインでもアクセス可能にしているだけなので、Azure Portal には b2clogin.com のエンドポイントしか表示されませんが、手動でホスト名を書き換えて確認します。

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

ログインを行って取得できた id_token を確認すると iss もカスタムドメインで設定したものになっています。ここはログインに使用したドメインがそのまま使われるようになっているようです。

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

これまで b2clogin.com を使っていたものをカスタムドメインに置き換える場合には、iss のチェックで既存のトークンがエラーになる場合がありそうなので、リリース計画を立てる必要がありそうです。

Identity Provider 側の設定を修正する

Facebook や Google といった OAuth 2 / OpenID Connect に対応した Identity Provider を使っている場合は、カスタムドメイン設定後はリダイレクト URL が変わるので、以下のようなエラーとなるはずです。

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

IdP の設定からリダイレクト URL をカスタムドメインを使用したものを追加するか、変更すればこれまで通りログイン可能です。忘れやすい部分だと思うので注意したいです。

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

リダイレクト URL は複数設定できることが多いので、変更ではなく追加のが安心です。

MSAL からカスタムドメインで利用する

最後に実際のアプリケーションから使うことを考えて、MSAL を使って試しておきました。まずは良く使いそうな MSAL.js でカスタムドメインを試してみます。

Azure AD B2C と MSAL.js 2.x の組み合わせは、少し前から認可コードフロー + PKCE 対応になっているので非常にすんなり使えます。

カスタムドメインになったからといっても、単純に MSAL に渡す設定に含まれている各 URL をカスタムドメインに置き換えるだけで問題なく扱えました。

const msalConfig = {
  auth: {
    clientId: "<clientid>",
    authority: "https://login.daruyanagi.com/<tenantid>/<policyname>",
    knownAuthorities: ["login.daruyanagi.com"]
  }
}

実行してみるとポップアップがカスタムドメインになっていることが確認できます。もちろんログインも問題なく行えたのでトークンが取得できました。

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

同様に MSAL.NET でも試してみます。デスクトップアプリケーションで試しているので設定は若干異なっていますが、内容としては MSAL.js の時と同じようにカスタムドメインに置き換えただけです。

WebView だとリダイレクト URL は表示されないので気にする必要はないのですが、折角なのでカスタムドメイン版に置き換えておきました。

var app = PublicClientApplicationBuilder.Create("<clientid>")
                                        .WithB2CAuthority("https://login.daruyanagi.com/tfp/<tenantid>/<policyname>")
                                        .WithRedirectUri("https://login.daruyanagi.com/oauth2/nativeclient")
                                        .Build();

var result = await app.AcquireTokenInteractive(null)
                      .ExecuteAsync();

Debug.WriteLine(result.AccessToken);
Debug.WriteLine(result.IdToken);

Azure AD B2C のアプリケーションのデフォルト設定では、カスタムドメイン版のリダイレクト URL は追加されないので、手動で追加して対応しました。

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

この設定で MSAL.NET でもカスタムドメインで問題なく動作しました。

全体的に見ると Front Door の設定が必要になるのは若干面倒な感じですが、カスタマイズした WAF を追加できる*1のは魅力になるかなと思いました。GA までにはデフォルトドメインでのアクセス拒否機能が組み込まれて欲しいですね。

*1:Preview 中は WAF を追加するのは推奨されていないっぽいみたいですが