本記事は Microsoft Learn の「Microsoft 認証ライブラリを使用して認証を実装する」というモジュールをまとめたものである。
Microsoft 認証ライブラリを調査する
Microsoft Authentication Library (MSAL) は、Microsoft ID プラットフォームからトークンを取得するための開発者向けライブラリ。これを使うことで、Microsoft Graph や独自の API への安全なアクセスを簡単に実装できる。
1. 主な役割とメリット
- 複雑なプロトコルの隠蔽:OAuth 2.0 や OpenID Connect の詳細な知識がなくても、簡単なコードで認証を実装可能
- トークンの自動管理:トークンのキャッシュ保持や、有効期限が切れる前の自動更新を代行。開発者が期限を監視する必要はない
- 多様なプラットフォーム対応:.NET, JavaScript, Python, Java ほか、Android/iOS などの主要環境を網羅
2. 開発に役立つ機能
- 一貫性のある API:どの言語・プラットフォームでも似たような書き方で利用できる
- 柔軟な認証対象:組織内のユーザーだけでなく、個人アカウントや B2C ユーザーなど、サインインさせる対象を容易に制御可能
- 運用のサポート:トラブルシューティングに不可欠なログ出力、テレメトリ(利用状況分析)、詳細なエラーメッセージ(例外)を提供
3. トークンの取得方法
- ユーザーの代理:ログイン中のユーザーとして API を叩くためのトークンを取得
- アプリ自身(プラットフォーム依存):バックグラウンド処理などでアプリ自体の権限としてトークンを取得
MSAL がサポートするアプリケーションとプラットフォーム
MSAL は、あらゆるアプリケーション形態(Web、モバイル、デスクトップ、サーバー等)に対応し、主要な言語やフレームワークでトークン取得を可能にする。
1. サポートされるアプリの種類
- フロントエンド:SPA(シングルページアプリ)、モバイル(iOS/Android)、デスクトップアプリ
- サーバーサイド:Web アプリ(Express/Next.js 等)、Web API、バックグラウンドで動くデーモン(サーバー側アプリ)
2. 主要ライブラリとプラットフォーム
多様な環境向けに最適化されたライブラリが提供されている。
| ライブラリ | 対応プラットフォーム / フレームワーク |
|---|---|
| MSAL.NET | .NET (Framework/Core), .NET MAUI, WinUI, Xamarin |
| MSAL.js / React / Angular | JavaScript/TypeScript, React, Angular, Vue.js, Next.js |
| MSAL Python / Java / Go | Windows, macOS, Linux (サーバー/コンソールアプリ) |
| MSAL Node | Node.js (Express), Electron (デスクトップ) |
| MSAL iOS / Android | iOS, macOS, Android (ネイティブアプリ) |
MSAL の主要な認証フロー
MSAL は、アプリの種類やデバイスの特性に合わせて、最適なトークン取得方法(フロー)を提供している。
1. 推奨される主要フロー
-
認証コードフロー (+ PKCE):最も一般的。ユーザーがログインし、アプリが「ユーザーの代理」として API にアクセスする
- 対象:Web、デスクトップ、モバイル、SPA
-
クライアント資格情報フロー:ユーザーの介在なしに「アプリ自身の ID」で認証する。サーバー間通信や自動スクリプト用
- 対象:デーモン、バックグラウンドジョブ
-
オンビハーフ・オブ (OBO):API が別の API を呼ぶ際に、元のユーザー情報を引き継ぐ
- 対象:Web API(中間層)
2. 特定のデバイス・環境向け
-
デバイスコードフロー:キーボード入力が難しいデバイス(スマートTV、IoT)や CLI で使用。別の端末でコードを入力して承認する
- 対象:デスクトップ、CLI、IoT
-
統合 Windows 認証 (IWA):ドメイン参加済みの PC で、ユーザー操作なし(サイレント)でログインする
- 対象:デスクトップ、モバイル
3. 非推奨・注意が必要なフロー
- 暗黙的な許可 (Implicit Grant):セキュリティ上の理由で現在は非推奨。認証コードフロー(PKCE)への移行が推奨される
- ユーザー名/パスワード (ROPC):アプリが直接パスワードを扱うため非推奨。多要素認証 (MFA) が使えないリスクがある
パブリッククライアントと機密クライアント
MSAL では、アプリケーションが「認証用シークレット(秘密鍵など)」を安全に隠し持てるかどうかで、クライアントを 2 種類に分類する。
1. パブリック クライアント (Public Client)
ユーザーの手元で動くため、秘密情報を隠し通せないアプリ。
- 実行環境:デスクトップ、モバイル、ブラウザ(SPA)、CLI
-
特徴:コードを逆コンパイルしたり、ブラウザのデバッグツールで見たりできるため、シークレットを保持できない
- 認証にはシークレットを使わず、ユーザーの代理としてのアクセスのみを行う
- 信頼性:アプリ自身の ID を完全に証明する能力は低い
2. 機密クライアント (Confidential Client)
ユーザーの手が届かない、保護されたサーバー上で動くアプリ。
- 実行環境:Web アプリ(サーバーサイド)、Web API、デーモン、バックグラウンドサービス
-
特徴:
- サーバー内に設定ファイルとしてシークレットを安全に保存できる
- ユーザーを介さない「バックチャネル」で認可サーバーと通信するため、機密情報が漏洩しない
- 信頼性:アプリ自身の ID を確実に証明でき、アプリ自身の権限での動作が可能
クライアントアプリケーションを初期化する
MSAL.NET 3.x 以降では、PublicClientApplicationBuilder または ConfidentialClientApplicationBuilder という「ビルダー」クラスを使用してアプリのインスタンスを作成する。
1. 事前準備:アプリの登録
初期化の前に Azure portal でアプリを登録し、以下の情報を取得しておく必要がある。
- アプリケーション(クライアント)ID:アプリを一意に識別する GUID 文字列
- ディレクトリ(テナント)ID:特定組織(シングルテナント)向けアプリの場合に必須
- 機関 (Authority):ID プロバイダーの URL とサインイン対象(全ユーザーか、特定組織のみか等)を組み合わせた情報
- リダイレクト URI:認証後にトークンを送信する先の URL。Web アプリやブローカー利用時に必要
2. クライアントの種類に応じた初期化
アプリの性質によって、使用するビルダーを使い分ける。
- パブリッククライアント:デスクトップ、モバイル用。シークレットは使用しない
-
機密クライアント:Web アプリ、API、デーモン用。以下のいずれかの「クライアント資格情報」が必要
- アプリケーションシークレット:文字列形式のパスワード
- 証明書:X509Certificate2 形式。より高いセキュリティが必要な場合に利用
3. 構成方法の柔軟性
- コードによる指定:プログラム内で直接パラメータを設定
-
構成ファイルからの読み込み:
appsettings.jsonなどから設定を反映 - ハイブリッド:両方を組み合わせて柔軟にセットアップ可能
MSAL.NET によるアプリケーションの初期化コード
C# を用いた、パブリッククライアントと機密クライアントの具体的なインスタンス化手順。
1. パブリッククライアントの初期化
デスクトップアプリやモバイルアプリなど、シークレットを持たない(持てない)アプリ用。
-
最小構成:
PublicClientApplicationBuilder.Create(clientId)を使用 - 対象:Azure パブリッククラウド上の「職場・学校アカウント」および「個人アカウント」
- 動作:ユーザーをサインインさせ、その代理で動くための基盤を作成する。
IPublicClientApplication app = PublicClientApplicationBuilder.Create(clientId).Build();
2. 機密クライアントの初期化
Web アプリや API など、サーバーサイドで秘密情報を保持できるアプリ用。
-
必須要素:
clientIdに加え、clientSecret(シークレット) とredirectUri(戻り先) を指定 - 識別方法:ID プロバイダー(Entra ID)に対し、共有されたシークレットを提示することでアプリ自身の正当性を証明する
- 対象:パブリッククライアントと同様、組織および個人のアカウントを処理可能
string redirectUri = "https://myapp.azurewebsites.net";
IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithClientSecret(clientSecret)
.WithRedirectUri(redirectUri )
.Build();
ビルダー修飾子(.With メソッド)による構成
MSAL のアプリケーション生成では、.With で始まるメソッド(修飾子)をチェーンさせて、詳細な設定を付加できる。
1. .WithAuthority 修飾子
認証の「発行元(オーソリティ)」を定義する。
- 役割:どのクラウドインスタンス(パブリック、政府用など)を使い、どのテナント(組織)に対して認証を行うかを設定
- 指定方法:テナント ID やドメイン名を渡すか、URI を直接指定する
- 活用例:特定の組織アカウント(シングルテナント)のみにサインインを制限したい場合に便利
IPublicClientApplication app;
app = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(AzureCloudInstance.AzurePublic, tenantId)
.Build();
2. .WithRedirectUri 修飾子
認証完了後にトークンを受け取る「戻り先 URL」を指定する。
- 役割:デフォルトの設定値を、アプリの種類や環境に合わせて上書きする
-
活用例:ローカル開発環境でのテスト用に
http://localhostを指定する場合など
IPublicClientApplication app;
app = PublicClientApplicationBuilder.Create(client_id)
.WithAuthority(AzureCloudInstance.AzurePublic, tenant_id)
.WithRedirectUri("http://localhost")
.Build();
アプリ共通のビルダー修飾子(.With メソッド)
MSAL.NET では、パブリック/機密クライアントを問わず、以下の修飾子を使ってアプリケーションの動作を詳細にカスタマイズできる。
1. 認証とネットワーク設定
-
.WithAuthority():認証の「発行元(オーソリティ)」を定義。Azure クラウドの種類(パブリック/政府用等)や、対象とするテナント(組織)を指定する -
.WithTenantId():特定のテナント ID を個別に指定、またはデフォルト値を上書きする -
.WithClientId():アプリケーション(クライアント)ID を上書きする -
.WithRedirectUri():認証後の戻り先 URL を指定。認証ブローカーを利用する場合などに重要
2. 診断とトラブルシューティング
-
.WithLogging():カスタムコールバックを設定し、認証プロセスの詳細なログを取得する -
.WithDebugLoggingCallback():有効にすると Debug.Write が実行され、開発時のトレースが容易になる -
.WithTelemetry():認証の成功率やパフォーマンス情報を送信するためのデリゲートを設定する
3. その他
-
.WithComponent():ライブラリを使用しているコンポーネント名を指定。主にテレメトリ(利用状況分析)での識別用
演習 - MSAL.NET を使用して対話型認証を実装する
まずは、アプリケーションを登録する。
「アプリの登録」>「新規登録」から

アプリの名前と、サポートされているアカウントの種類、リダイレクト URI を設定する。

概要ページからクライアントIDとテナントIDを確認する。
次に コンソールアプリを作成する。
ディレクトリを作成し、移動する。
mkdir authapp
cd authapp
コンソールアプリを作成する。
dotnet new console
必要なパッケージをインストールする。
dotnet add package Microsoft.Identity.Client
dotnet add package dotenv.net
.env ファイルを作成する。
touch .env
code .env
.env ファイルにクライアントIDとテナントIDを記載する。
CLIENT_ID="YOUR_CLIENT_ID"
TENANT_ID="YOUR_TENANT_ID"
Program.cs を修正する。
using Microsoft.Identity.Client;
using dotenv.net;
// Load environment variables from .env file
DotEnv.Load();
var envVars = DotEnv.Read();
// Retrieve Azure AD Application ID and tenant ID from environment variables
var _clientId = envVars["CLIENT_ID"];
var _tenantId = envVars["TENANT_ID"];
// ADD CODE TO DEFINE SCOPES AND CREATE CLIENT
// Define the scopes required for authentication
var _scopes = new[] { "User.Read" };
// Build the MSAL public client application with authority and redirect URI
var app = PublicClientApplicationBuilder.Create(_clientId)
.WithAuthority(AzureCloudInstance.AzurePublic, _tenantId)
.WithDefaultRedirectUri()
.Build();
// ADD CODE TO ACQUIRE AN ACCESS TOKEN
// Attempt to acquire an access token silently or interactively
AuthenticationResult result;
try
{
// Try to acquire token silently from cache for the first available account
var accounts = await app.GetAccountsAsync();
result = await app.AcquireTokenSilent(_scopes, accounts.FirstOrDefault())
.ExecuteAsync();
}
catch (MsalUiRequiredException)
{
// If silent token acquisition fails, prompt the user interactively
result = await app.AcquireTokenInteractive(_scopes)
.ExecuteAsync();
}
// Output the acquired access token to the console
Console.WriteLine($"Access Token:\n{result.AccessToken}");
アプリを実行する。
dotnet run
以下の様にコンソールに表示される。
Access Token:
eyJ0eXAiOiJKV1QiLCJub25jZSI6IlZF.........

