このように意気込んだものの、最初のログイン機能でつまづいてしまう、なんて話はよくあります(私です)。
実は Blazor ではユーザー認証機能が用意されているので、サインインやログインの処理は簡単に追加できるんです。
テンプレートを作成するときに「認証あり」として作成すれば、Identity Server を使用した認証機能が自動で追加されるようにもなっています。
本記事では、ユーザー管理を簡単にする「Azure Active Directory B2C」を Blazor に統合する手順について解説しました。
月間のアクティブユーザー(MAU)が 50,000 ユーザーまで無料なので、十分な容量ですね。
手順としては少し長いですが、途中を省略せずに解説しているので、迷うことなく進められると思います。
前置きはこれくらいにして、さっそく見ていきましょう。
テナントの作成
まずは、「テナント」というものを作成していきます。
普段の生活で「テナント募集中」という張り紙があるのを見たことがありませんか?
Azure でも同じで、「お店」みたいなイメージをもっていただくといいと思います。
では、Azure ポータルにアクセスして、「リソース」の追加を選択してください。

続いて、検索窓に「Azure Active Directory B2C」を入力して該当のサービスを探します。(長いので、以下 Azure AD B2C と表現します)

Azure AD B2C が表示されたら、作成ボタンを押しましょう。

新しい Azure AD B2C テナントを作成します。

組織名と初期ドメイン名は好きなもので構いません。
国は日本を選んでおきましょう。

サブスクリプションとリソースグループを選びます。
課金先みたいなイメージですね。
サブスクリプションの作成方法については、「追加 Azure サブスクリプションの作成」を参考にしてください。
入力ができたら「確認および作成」を選択します。

これでテナントの登録は完了なのですが、これだけでは使えません。
サブスクリプションに対して「Active Directory を使いますよ」という設定をする必要があります。
サブスクリプションのリソースプロバイダーを開き、「Microsoft.AzureActiveDirectory」を登録してあげましょう。

そして、先ほど作成したテナントがディレクトリとしてできているはずなので、ホーム画面から切り替えをしておきます。

これでテナントの準備が整いました。
アプリの登録(サーバー側)
Azure AD B2C にサーバー側のアプリを登録していきます。
「アプリの登録 > 新規登録」を選択してください。

アプリケーションの名前は何でもいいですが、「BlazorSignIn」としました。
サポートされているアカウントの種類は、「任意の ID プロバイダーまたは組織ディレクトリ内のアカウント(ユーザーフローを使用したユーザーの認証用)」を選択します。
ユーザーフローについては後で登録するので、今は気にしなくて大丈夫です。

リダイレクト URI は空欄にします(クライアント側のアプリで設定します)。
アクセス許可のチェックが付いていることを確認して、登録しましょう。

続いて、スコープの追加をしていきます。
API が許可する範囲を設定するイメージですね。
「API の公開 > Scope の追加」を選択してください。

画像では xxxx にしていますが、ランダムな文字列が自動生成されます。
そのまま「保存して続ける」を選択してください。

スコープ名は何でも構いません。
公式ドキュメントにしたがって、「API.Access」としました。
同意の表示名と同意の説明については、それっぽい内容を書いておけば OK です。
状態が「有効」になっていることを確認して、「スコープの追加」を選択してください。

これでサーバー側の登録は完了です。
アプリの登録(クライアント側)
次に、クライアント側のアプリを登録していきましょう。
名前は「BlazorSignInClient」としました。
サポートされているアカウントの種類は、「任意の ID プロバイダーまたは組織ディレクトリ内のアカウント(ユーザーフローを使用したユーザーの認証用)」を選択します。

クライアント側のアプリでは、リダイレクト URI(https://localhost:5001/authentication/login-callback)を設定します。
ローカルで試すので、localhost を指定しました。
アクセス許可のチェックが付いていることを確認して、登録しましょう。

続いて、「認証」のメニューを開き、次のふたつにチェックを付けて保存してください。
- アクセストークン(暗黙的なフローに使用)
- ID トークン(暗黙的およびハイブリッドフローに使用)

認証のところではもうひとつ操作があります。
URI リダイレクトの「→」を選択してください。

リダイレクト URI にチェックを付けて、構成ボタンを押せば完了です。

続いて、登録したスコープを許可するため「API のアクセス許可 > アクセス許可の追加」を選択します。

「自分のAPI」のタブを開き、サーバー側のアプリとして登録したものを選択します。

最初の方で追加した「API.Access」にチェックを付けて、アクセス許可の追加をします。

次に、いま追加した API.Access に対して、管理者の同意を与えてあげます。

API.Access の状態が
になっていれば OK です。
これでクライアント側のアプリ登録は完了しました。
ユーザーフローの作成
もう少し設定があるので、頑張りましょう。
Azure AD B2C の「ユーザーフロー > 新しいユーザーフロー」を選択して、ユーザーフローを追加していきます。

「サインアップとサインイン」を選択します。

「推奨」を選択して、作成します。

ユーザーフローの名前は好きな名前で構いません。

次に多要素認証についてです。
SMS/電話ベースの多要素認証を試行するたびに定額料金 ¥3.36 が請求されるので、どうしても必要な場合以外は設定しないほうがいいでしょう。
「条件付きアクセスポリシーを適用する」のチェックを外せば、メール認証だけになります。

あとは、ユーザーから収集する情報を選択していきます。
今回は表示名だけチェックをつけて、OK をしました。

これでユーザーフローの作成は完了です。
Blazor プロジェクトの作成
おまたせしました。
ようやく Blazor プロジェクトを作成することができます。
ターミナルで以下のコマンドを実行して、プロジェクトを作成していきます。
{} で表現しているところは、表の通り個別に値を設定してあげてください。
dotnet new blazorwasm -au IndividualB2C --aad-b2c-instance "{AAD B2C INSTANCE}" --api-client-id "{SERVER API APP CLIENT ID}" --app-id-uri "{SERVER API APP ID URI}" --client-id "{CLIENT APP CLIENT ID}" --default-scope "{DEFAULT SCOPE}" --domain "{TENANT DOMAIN}" -ho -o {APP NAME} -ssp "{SIGN UP OR SIGN IN POLICY}" -f net7.0
プレースホルダー | 意味 | 例 |
---|---|---|
{AAD B2C INSTANCE} | インスタンス名 | https://nekojoker.b2clogin.com/ |
{SERVER API APP CLIENT ID} | サーバー側のアプリID | 6518a3e3-b571-4402-bddd-e89f29bafa3e |
{SERVER API APP ID URI} | サーバー側のアプリ URI | 6518a3e3-b571-4402-bddd-e89f29bafa3e |
{CLIENT APP CLIENT ID} | クライアント側のアプリID | 3b8ab272-3eb2-486a-a3bf-3c661ed46d44 |
{DEFAULT SCOPE} | スコープ名 | API.Access |
{TENANT DOMAIN} | ドメイン名 | nekojoker.onmicrosoft.com |
{APP NAME} | アプリ名 | これから作るプロジェクト名 |
{SIGN UP OR SIGN IN POLICY} | サインアップまたはサインインポリシー | B2C_1_Signin |
いきなり .NET 8 の状態では作成できないため、.NET 7 でテンプレートを作成するよう指定しています。
.NET 8 で使用したい場合は、テンプレート作成後に手動で .NET 8 に上げる必要があります。
上げる作業が面倒な場合は.NET 8 のテンプレートを GitHub で用意しているので、こちらを使用してください。
アプリ URI のところは、スコープを追加するときに指定した URL の初期値がサーバー側のアプリ ID と一緒になっています。
コマンドを実行してプロジェクトの作成ができたら、動作確認をしていきましょう。
デバッグ実行をすると、Hello World が表示されます。
この画面はログインをしていなくても見ることができます。

「Fetch data」のメニューを選択すると、ログイン画面が出てきました。
「Fetch data」は Home とは違って、認証されていないと見ることができないページだからですね。

まだアカウントがないので、下の方にある「Sign up now」を選択して、メールアドレスから認証コードを送信します。

届いた認証コードを入れて、パスワードとユーザー名を入力したら「Create」を押しましょう。

無事に認証が完了して、Fetch data のページを見ることができました。
画面の右上には、先ほど登録したユーザー名も表示されていることが確認できますね。

また、Azure AD B2C の画面から見ても、ユーザーが登録されていることが確認できます。

ログイン画面の日本語化
ログイン画面が英語なので、日本語にしていきましょう。
ユーザーフローの「言語のカスタマイズの有効化」から、カスタマイズを有効にします。

日本語を既定値で有効にし、保存しましょう。

英語は使わないので、無効にしておきます。

この状態でもう一度ログイン画面を表示してみると、日本語で表示されていることが確認できました。

もし文言を変えたい場合は、設定画面から所定の JSON ファイルをアップロードすることで、文言をオーバーライドすることも可能です。
まとめ
Blazor の認証機能を Azure AD B2C を使って実現する方法について解説しました。
「なんだかうまくいかない」という人は、参考にした記事や動画を載せておくので、チェックしてみてください。
また、プログラム的にどうなっているのかについても、以下の記事に詳しく書いてあります。

入門編から EC サイトを作る応用編まで、Blazor の本を3冊執筆しました。
私が1年以上かけて学習した内容をすべて詰め込んでいるので、さらにステップアップしたい方はぜひご覧ください。