mcpField
M
maui-authentication

maui-authentication

github.com/davidortinauセキュリティ17654 回インストール16 週間前に更新
リポジトリ

maui-authentication について

OAuth や Microsoft Entra ID のサインインを実装する .NET MAUI 開発者向けの認証ガイダンススキルです。安全なトークンフロー、プラットフォーム固有の設定上の注意点、WebAuthenticator と MSAL.NET の使い分けを説明します。

主な機能

  1. 01安全な OAuth フローの設計
  2. 02WebAuthenticator の設定と注意点
  3. 03WebAuthenticator と MSAL.NET の選択指針
  4. 04MSAL.NET のプラットフォーム設定確認
  5. 05Blazor Hybrid の認証パターン

活用シーン

  1. 01汎用 OAuth または OIDC サインインの実装
  2. 02Microsoft Entra ID 認証の追加
  3. 03コールバック URI の不一致の調査
  4. 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 キー、署名キーをモバイルアプリのバイナリに決して埋め込まないでください。 逆コンパイルによって簡単に抽出される可能性があります。

正しいパターン:

  1. アプリが WebAuthenticator を呼び出し、自分のサーバーのエンドポイントを指定します
  2. サーバーが ID プロバイダーとの OAuth フローを開始します(クライアントシークレットを保持します)
  3. プロバイダーが認証コードとともにサーバーへリダイレクトします
  4. サーバーがコードをトークンと交換し、コールバック 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 の選択

基準WebAuthenticatorMSAL.NET
ID プロバイダー任意の OAuth 2.0/OIDCMicrosoft Entra ID
ブローカーのサポート(SSO)❌ なし✅ Microsoft Authenticator、Company Portal
条件付きアクセス/MFA❌ 手動✅ 組み込み
トークンキャッシュと更新❌ 手動(SecureStorage)✅ 自動
複雑さシンプル追加設定が必要
使用する場合Google、Apple、汎用 OIDCEntra 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 パターンは使用しないでください。代わりに、次のようにします。

  1. MAUI が IAuthService(MSAL.NET)を介してサインインを処理します
  2. カスタムの MsalAuthenticationStateProvider が Blazor に認証状態を公開します
  3. DelegatingHandler を使用する HttpClient がベアラートークンを自動的に付加します

MSAL.NET チェックリスト

  • Microsoft.Identity.Client NuGet パッケージを追加済み
  • 正しいリダイレクト 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 を適切に処理する

コメント