今回はC#BlazorアプリへMicrosoft EntraID(旧Azure Active Directory)認証を組み込む方法を解説します。
本記事では、以下について説明します。
- Microsoft Entra IDとは何か?
- Blazorアプリ上へEntraIDを組み込む方法
次のような人に役立つ内容になっています。
- EntraID認証を行うBlazorアプリを作りたい。
- とにかく簡単に外部プロバイダ認証をBlazorアプリへ組み込んでみたい。
- BlazorとAzureと組み合わせて何かしたい!
以下のようなEntraID認証が行える簡単なBlazorアプリを作ります。
EntraIDは企業においてMicrosoftエコシステムの認証基盤として広く使われています。
Entra ID認証できるBlazorアプリは、シングルサインオン(SSO)でMicrosoft製品(例: Office 365、Teams、Azureサービス)とシームレスに連携できるでしょう。
今回の内容はEntraID認証アプリ作成の第一歩です!
Azure上での設定方法を含めて一緒に学んでいきましょう。
演習のコード一式はGitHubにも置いてありますので、参考にしてください。
YouTubeの動画も作成しています。
講義:Microsoft Entra ID認証とは?
Microsoft Entra ID
Microsoft Entra IDは外部認証プロバイダの1つです。
外部認証プロバイダは、ユーザ認証・ユーザ管理機能をクラウドサービスとして提供してくれています。
Microsoftは以下の2つの外部認証プロバイダを用意しています。今回は(1)についての説明です。
- (1) Entra ID:主に企業や組織内の社員やパートナー向け。
- (2) Azure Active Directory B2C: 一般消費者向け。
Entra IDの主な特徴は以下のとおりです。
- ID管理:ユーザ情報を一元管理。例えば、入社や異動時の権限設定が簡単にできます。
- シングルサインオン(SSO):1つのアカウントで複数のアプリへ認証。
- 多要素認証(MFA):パスワード以外の認証方法に対応。例えば、スマホでの認証など。
- 条件付きアクセス:「誰が」「どこから」「何を使って」アクセス可能かを制御可能。例えば、会社で配布したデバイスからのみアクセス許可など。
Entra IDはMicrosoftエコシステムとの相性の良さもあり、多くの企業で使われています。
外部認証プロバイダはMicrosoft以外にも、Google、Facebook、Amazon、Okta、Auth0など様々な企業が提供しています。
(2) Azure AD B2C認証の導入については以下の記事で解説していますので、興味があったらぜひこちらもご覧ください。
BlazorとEntra ID認証
Blazorのユーザ認証・管理機能の実現には以下の方法があります。
- (a)ASP.NET Core Identityを使う。
- (b)外部認証プロバイダを使う。
- (c)独自で実装する。
今回は(b)の方法ということになります。
(a),(b),(c)がどのような方法か、どのように選択すればよいかといった話や、(a)Core Identityによるユーザ認証の実装方法については以下の記事を参考にしてください。
ASP.NET Core BlazorはMicrosoftエコシステムの一部ということもあり、EntraID認証の導入は外部認証プロバイダの中では比較的容易です。
外部認証プロバイダって、設定とかいろいろあって難しいんだよね…。
Blazor(特にServerモード)へのEntra ID導入は手順が(他に比べると)少なめかなとは思います。
あと、Azureに慣れておくと今後できることの幅も広がるので、頑張りましょう!
演習:Microsoft EntraIDによる認証機能を作る
Blazor(Serverモード)のアプリへEntra ID認証を追加し、最小限のログイン・ログアウト機能がついたものを作ります。
以下の手順で作ります。
- 手順1:Azureの環境構築と設定
- 手順2:Blazorアプリを実装
手順1:Auzreの環境構築と設定
以下の手順でEntraIDを使うためのAzure環境を構築します。
- 手順1-1:アカウント作成とサブスクリプション・テナント作成
- 手順1-2:アプリを登録
- 手順1-3:テスト用のユーザを登録
Azureの構成はざっくりと以下のようになります(色をつけた部分が、今回の設定で使う部分です)。
Microsoftアカウントに対応したAzure環境が1つ存在し、Azure環境内ではテナントを複数作れます。
テナントは1つの組織(例:会社)に対応します。
サブスクリプションはAzureのサービス・リソースを使うための契約単位です。(1つの支払い用クレジットカードに対応していると考えればよいでしょう)
Entra IDは組織(テナント)のユーザを管理します。
Entra IDにはアクセス管理の設定を行う「アプリ」を複数登録できます。
BlazorアプリはこのEntraIDに登録された「アプリ」を経由してEntra IDを利用してユーザ認証/管理を行います。
今回は使いませんが、サブスクリプションは各種リソース(仮想マシン・ストレージ等)の支払いにも使われます。
それでは、具体的な手順をみていきましょう。
手順1-1:アカウント作成とサブスクリプション・テナント作成
Microsoftアカウントが必要になるため、ない場合はこちらを参考にして作りましょう。
Microsoft Azure portalでサインインします。
アカウントへ二段階認証も設定しておくとよいでしょう。
最初にサブスクリプションを作成します。「Azureの無料使用版から開始する」の開始をクリックしましょう。
以下の画面へ遷移するので、「Try Azure for free」をクリックします。
以下のように、プロフィールやクレジットカード情報を入力する画面になりますので、入力しましょう。
クレジットカードを登録しますが、今回紹介するMicrosoft Entra IDの基本的な機能は無料で使えます。
Azureでは無料枠で使えるサービスもたくさんありますね。
オーソリチェックで一時的に100円程度支払いが発生するかもしれませんが、これは通常数日以内に自動返却されます。
手順1-2:アプリを登録
左上の三本線アイコンをクリックしましょう。
「Microsoft Entra ID」を選びましょう。
Default Directoryの画面が表示されます。「管理>アプリ登録」をクリックします。
「+新規登録」をクリックします。
アプリケーションの登録で、以下のように設定して登録しましょう。
名前は好きなもので構いません。リダイレクトURIは、ひとまずローカルでデバッグすることを想定して「https://localhost:5001/signin-oidc」と設定しています。
(本番環境のURIが必要であれば、それも追加します)
アプリ登録ができたら、Default Directoryで「アプリの登録」を選択し、「すべてのアプリケーション」を選択すると、登録したものが表示されます。これをクリックしましょう。
「管理>証明書とシークレット」を選び、クライアントシークレットを追加しましょう。
作成した「クライアントシークレットの値」をメモしておきましょう。
次に、「概要」を選択し、以下をメモしておきましょう。Blazorアプリ側の設定で必要になります。
- アプリケーション(クライアント)ID
- ディレクトリ(テナント)ID
手順1-3:テスト用のユーザを登録
テスト用にユーザを登録します。
Default Directoryで「管理>ユーザー」を選択しましょう。
「新しいユーザー>新しいユーザの作成」を選択します。
以下のように、ID、表示名、パスワード(デフォルトでは自動生成)を設定して新しいユーザを作成しましょう。
ユーザプリンシパル名「testuser1@XXXX.onmicrosoft.com」は、ログイン時にIDとして使うので、ドメイン部分(XXXX.onmicrosoft.com)も含めてメモしておきましょう。
パスワードもメモしておきましょう。初回ログイン時に必要です。
「次のプロパティ」を選択すると、より詳細なユーザの各種プロパティを設定することもできます。
設定したら「レビューを作成」をクリックします。
以下のように確認画面が表示されるので、「作成」をクリックしましょう。これで新規ユーザ作成完了です。
Default Directoryで「すべてのユーザ」を選択すると、新しく追加したユーザを確認できます。
これで、テスト用のユーザを使えるようになりました。
手順2:Blazorアプリを実装
以下の手順でEntraID認証を行うBlazorアプリを作ります。
- 手順2-1:プロジェクトひな型を準備
- 手順2-2:コードを修正
- 手順2-3:設定ファイルを修正
プロジェクトひな型で、以下の部分を修正します。
手順2-1:プロジェクトひな型を準備
以下のコマンドで、Blazor Severモードのプロジェクトを作成しましょう。
dotnet new blazor -n BlazorEntraIDApp1 -o BlazorEntraIDApp1 -f net8.0 --interactivity Server
Visual Studioでプロジェクトファイル「BlazorEntraIDApp1.csproj」を開きます。
「ファイル>全て保存」で、「BlazorEntraIDApp1.csproj」と同じフォルダへソリューションファイル「BlazorEntraIDApp1.sln」を保存しておきましょう。
以下の3つのパッケージをインストールしておきます。
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Identity.Web.UI
手順2-2:コードを修正
Program.csを修正します。
using BlazorEntraIDApp1.Components;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
var builder = WebApplication.CreateBuilder(args);
//★(a) Configure Azure AD Authentication using OpenID Connect
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
//★(b) Add Razor Pages and Microsoft Identity UI for authentication-related pages (e.g., login, logout)
builder.Services.AddRazorPages()
.AddMicrosoftIdentityUI();
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
//★(c) Enable routing for authentication-related UI pages provided by AddMicrosoftIdentityUI()
app.MapControllers();
app.Run();
(a),(b),(c)で、アプリでEntraID認証を使うための設定を行っています。
(a)で設定ファイルの情報をもとにEntraID認証を使えるようにし、(b)でログイン画面等の認証関連画面を使えるようにし、(c)でその画面へのルーティングを設定しています。
次に、Components/Layout/NavMenu.razorへログイン/ログアウト用のリンクを追加します。それぞれ(a),(b)の部分です。
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">BlazorEntraIDApp1</a>
</div>
</div>
<input type="checkbox" title="Navigation menu" class="navbar-toggler" />
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="weather">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
</NavLink>
</div>
@*★(a)*@
<div class="nav-item px-3">
<a href="MicrosoftIdentity/Account/SignIn" class="nav-link">Login</a>
</div>
@*★(b)*@
<div class="nav-item px-3">
<a href="MicrosoftIdentity/Account/SignOut" class="nav-link">Logout</a>
</div>
</nav>
</div>
Compornents/Pages/Home.razorを以下のように修正しましょう。認証されていればユーザ名を、そうでなければGuestと表示するようにしています。
@page "/"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider
<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<p>Welcome, @userName!</p>
@code {
private string userName;
protected override async Task OnInitializedAsync()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity.IsAuthenticated)
{
userName = user.Identity.Name;
}
else
{
userName = "Guest";
}
}
}
手順2-3:設定ファイルを修正
appsettings.jsonへ(a)のようにAzureADの項目を追記します。(b)テナントID、(c)クライアントID、(d)クライアントシークレットはメモしておいたものを記載しましょう。
{
//★(a)
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "★(b)テナントIDを記載",
"ClientId": "★(c)クライアントIDを記載",
"ClientSecret": "★(d)クライアントシークレットを記載"
"ResponseType": "code" // 認可コードフローを使う
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
クライアントシークレットは機密性が高いため、絶対に他人に知られないよう注意してください。
ここではappsettings.jsonに直接記載していますが、環境変数にしてコードベースから分離した方が安全です。
Properties/launchSettings.jsonで、profiles/https/applicationUrlで起動ポート((a)の部分)を「https://localhost:5001」と修正します。
…
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5050", //★(a)
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
…
アプリ登録のときのリダイレクトURIとあっていればポート番号は何でもよいです。
デバッグ実行のプロファイルとして「https」を選ぶことを想定しています。
アプリを実行する
Visual Studioでプロファイルをhttps(デフォルト設定)としてデバッグ実行しましょう。
未ログインではHomeは以下のような画面です。
Loginボタンをクリックしてログインしてみましょう。パスワードは新規ユーザ作成時に設定したものを入力します。
初回ログイン時は、パスワードの更新を求められます。
以下の警告がでますので、「承諾」をクリックしましょう。
以下のように、Microsoft Atuthenticatorによる多要素認証を求められたら、手順に従って設定しましょう。
Microsoftはセキュリティ強化のため、2024年後半からAzureにおける多要素認証を段階的に強制化していく予定です。(参考記事)
これでログインできました。Home画面で「Welcome, testuser1@…」と表示されます。
これで、Entra IDによる認証機能を備えたBlazorアプリの第一歩ができました!
ログアウトなども試してみてください。
社内でMicrosoft Entra IDを使っているから、それと連携したシングルサインオンのアプリを作れるかも!
EntraIDを使うと、多要素認証やメールを使ったパスワードリセットなども比較的容易に追加できます。
EntraIDについてより詳しく知りたい場合、Microsoft Entra IDのドキュメントも参考にしてください。
Entra IDではデフォルトではユーザIDのドメイン名が初期ドメイン(XXX.onmicrosoft.com)となります。
これをカスタムドメイン(例:prota-p.com)にする方法は以下の記事を参考にしてください。
まとめ
Blazorへ外部認証プロバイダであるEntra IDを組み込む方法を学びました。
Entra ID認証を備えたBlazorアプリ開発の第一歩ですね。
Azureを初めて使うという方は、Azureの雰囲気も少しわかったのではないでしょうか。
Blazor(Serverモード)だと特にEntraID認証は簡単ですが、「WASMアプリ+APIバックエンド」や「WASMアプリ(Self-Hosted)」の場合はもうひと手間必要になります。
引き続き、Webアプリ開発とBlazorを一緒に学んでいきましょう!