maui-authentication について
OAuth や Microsoft Entra ID のサインインを実装する .NET MAUI 開発者向けの認証ガイダンススキルです。安全なトークンフロー、プラットフォーム固有の設定上の注意点、WebAuthenticator と MSAL.NET の使い分けを説明します。
主な機能
- 01安全な OAuth フローの設計
- 02WebAuthenticator の設定と注意点
- 03WebAuthenticator と MSAL.NET の選択指針
- 04MSAL.NET のプラットフォーム設定確認
- 05Blazor Hybrid の認証パターン
活用シーン
- 01汎用 OAuth または OIDC サインインの実装
- 02Microsoft Entra ID 認証の追加
- 03コールバック URI の不一致の調査
- 04Blazor Hybrid での認証処理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ davidortinau/ maui-skills --skill maui-authenticationインストール後、Claude Code で/maui-authenticationを入力して読み込まれたか確認します。
同梱ファイルreferences/authentication-api.md
詳細
.NET MAUI 認証
セキュリティ:シークレットを決して埋め込まないでください
❌ クライアントシークレット、API キー、署名キーをモバイルアプリのバイナリに決して埋め込まないでください。 逆コンパイルによって簡単に抽出される可能性があります。
正しいパターン:
- アプリが
WebAuthenticatorを呼び出し、自分のサーバーのエンドポイントを指定します - サーバーが ID プロバイダーとの OAuth フローを開始します(クライアントシークレットを保持します)
- プロバイダーが認証コードとともにサーバーへリダイレクトします
- サーバーがコードをトークンと交換し、コールバック URI を介してアプリに返します
WebAuthenticator の注意点
⚠️ Windows の WebAuthenticator は正常に動作しません
Windows の WebAuthenticator は現在正常に動作しません。dotnet/maui#2702 を参照してください。Windows の認証フローには、MSAL または WinUI 固有の回避策を使用してください。
⚠️ Apple Sign In が名前/メールアドレスを返すのは一度だけです
Apple がユーザーの名前とメールアドレスを返すのは、初回のサインイン時だけです。すぐにキャッシュしてください。2 回目以降のサインインでは返されません。
⚠️ PrefersEphemeralWebBrowserSession
新しいログインプロンプトを強制するには、iOS 13 以降で true に設定します。false(既定値)の場合、認証セッションは Safari と Cookie を共有します。ユーザーが自動的にログインする可能性があり、ログアウトやアカウント切り替えのフローで混乱を招くことがあります。
⚠️ コールバック URI の不一致
最もよくある認証エラーは、URI スキームの不一致です。コード内の CallbackUrl は、次の設定と完全に一致する必要があります。
- Android:
IntentFilter内のDataScheme+DataHost - iOS:
Info.plist内のCFBundleURLSchemes - Windows:
Package.appxmanifest内のProtocol Name
WebAuthenticator チェックリスト
- すべてのプラットフォーム設定と
CallbackUrlでコールバック URI スキームが一致している - Android に正しい
IntentFilterを持つWebAuthenticatorCallbackActivityがある - Android 11 以降で、マニフェストに Custom Tabs 用の
<queries>がある - iOS/Mac Catalyst の
Info.plistにCFBundleURLTypesがある - クライアントシークレットがアプリ内ではなくサーバー上にある
- トークンが
SecureStorageに保存され、ログアウト時に消去される - UI で
TaskCanceledExceptionが適切に処理される
WebAuthenticator と MSAL.NET の選択
| 基準 | WebAuthenticator | MSAL.NET |
|---|---|---|
| ID プロバイダー | 任意の OAuth 2.0/OIDC | Microsoft Entra ID |
| ブローカーのサポート(SSO) | ❌ なし | ✅ Microsoft Authenticator、Company Portal |
| 条件付きアクセス/MFA | ❌ 手動 | ✅ 組み込み |
| トークンキャッシュと更新 | ❌ 手動(SecureStorage) | ✅ 自動 |
| 複雑さ | シンプル | 追加設定が必要 |
| 使用する場合 | Google、Apple、汎用 OIDC | Entra ID/Azure AD、Microsoft Graph |
MSAL.NET の注意点
⚠️ Android:OnActivityResult が必要です
MainActivity.OnActivityResult で AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs を呼び忘れると、ブラウザーから戻った後に認証が何も表示されずに停止します。
⚠️ iOS:キーチェーン共有が必要です
キーチェーングループ com.microsoft.adalcache を含む Entitlements.plist がない場合、トークンのキャッシュはエラーを表示せずに失敗し、ユーザーは毎回サインインを求められます。
⚠️ MsalUiRequiredException を処理する
AcquireTokenSilent が MsalUiRequiredException をスローした場合、キャッシュされたトークンの有効期限が切れており、対話が必要です。必ず AcquireTokenInteractive にフォールバックしてください。
// ❌ Ignoring MsalUiRequiredException — user gets a crash
var result = await _pca.AcquireTokenSilent(scopes, account).ExecuteAsync(ct);
// ✅ Fall back to interactive when silent fails
try
{
result = await _pca.AcquireTokenSilent(scopes, account).ExecuteAsync(ct);
}
catch (MsalUiRequiredException)
{
result = await _pca.AcquireTokenInteractive(scopes).ExecuteAsync(ct);
}
⚠️ ユーザーによるキャンセルを適切に処理する
// ✅ Don't treat cancellation as an error
catch (MsalClientException ex) when (ex.ErrorCode == "authentication_canceled")
{
return null; // User cancelled — not an error
}
⚠️ Blazor Hybrid:認証は MAUI レイヤーで行います
MAUI Blazor Hybrid アプリでは、認証は Blazor WebView ではなく、MAUI レイヤー(MSAL.NET)で行う必要があります。AddMicrosoftIdentityWebApp やサーバー側の OIDC パターンは使用しないでください。代わりに、次のようにします。
- MAUI が
IAuthService(MSAL.NET)を介してサインインを処理します - カスタムの
MsalAuthenticationStateProviderが Blazor に認証状態を公開します DelegatingHandlerを使用するHttpClientがベアラートークンを自動的に付加します
MSAL.NET チェックリスト
-
Microsoft.Identity.ClientNuGet パッケージを追加済み - 正しいリダイレクト URI を設定して、Entra ID にアプリ登録を作成済み
-
AuthConfig/appsettings.jsonに ClientId、TenantId、Scopes を設定済み - Android:
AndroidManifest.xmlにブローカーとブラウザー用の<queries>を設定済み - Android:
MainActivity.OnActivityResultでAuthenticationContinuationHelperを呼び出す - iOS:
Info.plistのCFBundleURLSchemesにmsauth.{BundleId}を設定済み - iOS:
Entitlements.plistにキーチェーングループcom.microsoft.adalcacheを設定済み - iOS:
AppDelegate.OpenUrlでAuthenticationContinuationHelperを呼び出す - DI で
IAuthServiceをシングルトンとして登録済み - API 呼び出し用の
HttpClientにDelegatingHandlerを追加済み - ログイン/ログアウトの UI を接続済み
-
MsalUiRequiredExceptionを処理する(対話型サインインを開始) -
authentication_canceledが発生した場合のMsalClientExceptionを適切に処理する