> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# .NET MAUI アプリケーションにLogin機能を追加する

> このガイドでは、Auth0.OidcClient.MAUI SDK を使用して、.NET MAUI アプリケーションに Auth0 を統合する方法を説明します。

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

<HowToSchema />

<Accordion title="AI を使って Auth0 を統合する" icon="microchip-ai" iconType="solid" defaultOpen>
  Claude Code、Cursor、GitHub Copilot などの AI コーディングアシスタントを使えば、[agent skills](https://agentskills.io/home) を利用して、数分で Auth0 認証を自動的に追加できます。

  **インストール:**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0
  ```

  **次に、AI アシスタントに次のように依頼します:**

  ```text theme={null}
  Add Auth0 authentication to my .NET MAUI app
  ```

  AI アシスタントが、Auth0 アプリケーションの作成、資格情報の取得、Auth0 OidcClient MAUI SDK のインストール、コールバック URL の設定、Login/ログアウト フローの実装を自動的に行います。[agent skills の完全なドキュメント →](/docs/ja-jp/quickstart/agent-skills)
</Accordion>

このガイドでは、[Auth0.OidcClient.MAUI SDK](https://github.com/auth0/auth0-oidc-client-net) を使用して、.NET MAUI アプリケーションに Auth0 を統合する方法を紹介します。この手順を終えると、単一のコードベースで **Android**、**iOS**、**macOS**、**Windows** に対応し、Login、ログアウト、ユーザープロファイル情報の表示をアプリでサポートできるようになります。

このガイドでは、`Auth0.OidcClient.MAUI` バージョン **1.x** を使用します。

<Note>
  ## 前提条件

  * **.NET 8 または .NET 9 SDK** がインストールされていること ([ダウンロード](https://dotnet.microsoft.com/download))
  * **.NET MAUI ワークロード** がインストールされていること
  * **Auth0 アカウント** を持っていること ([無料でサインアップ](https://auth0.com/signup))
  * .NET MAUI 拡張機能を備えた **Visual Studio 2022** (17.8 以降) 、**JetBrains Rider**、または **VS Code**
</Note>

環境を確認します。

```shellscript theme={null}
dotnet --version        # 8.x または 9.x であること
dotnet workload list    # maui が含まれていること
```

MAUI ワークロードがない場合は、インストールしてください。

```shellscript theme={null}
dotnet workload install maui
```

<div id="get-started">
  ## はじめに
</div>

<Steps>
  <Step title="Auth0アプリケーションの設定" stepNumber={1}>
    MAUI アプリに必要な資格情報を取得できるよう、Auth0 アプリケーションを設定します。

    1. **[Auth0 Dashboard](https://manage.auth0.com/dashboard/) > アプリケーション > アプリケーション** に移動します
    2. **Create Application** を選択します
    3. アプリの名前 (例: "My MAUI App") を入力し、アプリケーションの種類として **Native** を選択して、**Create** をクリックします
    4. Application Details ページの **Settings** タブに移動します
    5. **Domain** と **Client ID** の値を控えます。これらは後で必要になります

    **Settings** タブで **Application URIs** までスクロールし、次の URL を設定します。.NET MAUI アプリでは、HTTP URL ではなくカスタム URI スキーム (例: `myapp://callback`) を使用します。

    **Allowed Callback URLs:**

    ```text theme={null}
    myapp://callback
    ```

    **許可されたログアウト後のURL:**

    ```text theme={null}
    myapp://callback
    ```

    <Tip>
      アプリごとに一意のスキームを選択してください。たとえば、`com.mycompany.myapp://callback` のような逆順ドメイン名が適しています。
    </Tip>

    **変更を保存** を選択します。

    <Check>
      Auth0 にネイティブアプリケーションがあり、**Domain** と **Client ID** を控えていて、コールバックURL とログアウトURL が設定されていることを確認してください。
    </Check>
  </Step>

  <Step title="MAUI プロジェクトを作成する" stepNumber={2}>
    すでに .NET MAUI プロジェクトがある場合は、手順 3 に進んでください。まだない場合は、.NET CLI を使用して作成します。

    ```shellscript theme={null}
    dotnet new maui -n MyMauiApp
    cd MyMauiApp
    ```
  </Step>

  <Step title="Auth0 MAUI SDKのインストール" stepNumber={3}>
    プロジェクトに `Auth0.OidcClient.MAUI` NuGet パッケージを追加します：

    ```shellscript theme={null}
    dotnet add package Auth0.OidcClient.MAUI
    ```

    <Check>
      `dotnet restore` を実行し、パッケージが正常にインストールされたことを確認します。
    </Check>
  </Step>

  <Step title="プラットフォームごとのコールバック処理を設定する" stepNumber={4}>
    .NET MAUIアプリでは、認証後にシステムブラウザーからアプリへリダイレクトできるよう、各プラットフォームでコールバック ハンドラーを登録する必要があります。対象の各プラットフォームについて、以下の手順に従ってください。

    <Tabs>
      <Tab title="Android">
        `Platforms/Android/WebAuthenticatorActivity.cs` に新しいファイルを作成します。

        ```csharp Platforms/Android/WebAuthenticatorActivity.cs lines theme={null}
        using Android.App;
        using Android.Content;
        using Android.Content.PM;

        namespace MyMauiApp.Platforms.Android;

        [Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
        [IntentFilter(new[] { Intent.ActionView },
                      Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
                      DataScheme = CALLBACK_SCHEME)]
        public class WebAuthenticatorActivity : Microsoft.Maui.Authentication.WebAuthenticatorCallbackActivity
        {
            const string CALLBACK_SCHEME = "myapp";
        }
        ```

        `myapp` を、ステップ 1 で設定した URI スキームに置き換えます。

        <Note>
          `CALLBACK_SCHEME` の値は、`RedirectUri` のスキームおよび Auth0 の **Allowed Callback URLs** と完全に一致している必要があります。
        </Note>
      </Tab>

      <Tab title="Windows">
        Windows での Auth0 コールバック フローは URI プロトコルのアクティブ化に依存しているため、アプリは **パッケージ化** (MSIX) されている必要があります。既定の .NET MAUI テンプレートではパッケージ化されたアプリが作成されるため、`dotnet new maui` または Visual Studio の MAUI テンプレートを使用した場合は変更不要です。

        <Info>
          `.csproj` に `<WindowsPackageType>None</WindowsPackageType>` が含まれている場合、アプリは **非パッケージ化** されており、プロトコルのアクティブ化は機能しません。その行を削除するか、`<WindowsPackageType>MSIX</WindowsPackageType>` に設定してパッケージ化されたアプリを使用してください。詳しくは、[.NET MAUI の Windows パッケージ化に関するドキュメント](https://learn.microsoft.com/en-us/dotnet/maui/windows/deployment-overview)を参照してください。
        </Info>

        必要な変更は 2 つあります。URI プロトコルの登録と、プロトコル アクティブ化の処理です。

        **1. プロトコルを登録する** `Platforms/Windows/Package.appxmanifest` で、既存の `<Application>` 要素内に `<Extensions>` ブロックを追加します。

        ```xml Platforms/Windows/Package.appxmanifest lines theme={null}
        <Applications>
          <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
            <Extensions>
              <uap:Extension Category="windows.protocol">
                <uap:Protocol Name="myapp"/>
              </uap:Extension>
            </Extensions>
          </Application>
        </Applications>
        ```

        **2. アクティブ化を処理する** `Platforms/Windows/App.xaml.cs` で、コンストラクターの **先頭行** に `CheckRedirectionActivation` の呼び出しを追加します。

        ```csharp Platforms/Windows/App.xaml.cs lines theme={null}
        public App()
        {
            if (Auth0.OidcClient.Platforms.Windows.Activator.Default.CheckRedirectionActivation())
                return;

            this.InitializeComponent();
        }
        ```
      </Tab>

      <Tab title="iOS / macOS">
        プラットフォーム固有の設定は不要です。SDK は MAUI の `WebAuthenticator` を通じて、自動的に `ASWebAuthenticationSession` を使用します。
      </Tab>
    </Tabs>
  </Step>

  <Step title="ログインとログアウトを追加" stepNumber={5}>
    3 つのファイルを作成または変更する必要があります。ログイン/ログアウト ロジックを含む ViewModel、UI 用の XAML ページ、そしてそれらを連携させるコードビハインド ファイルです。

    <Tabs>
      <Tab title="MainPageViewModel.cs">
        `ViewModels/MainPageViewModel.cs` に ViewModel を作成します。

        ```csharp ViewModels/MainPageViewModel.cs lines theme={null}
        using System.ComponentModel;
        using System.Runtime.CompilerServices;
        using System.Windows.Input;
        using Auth0.OidcClient;

        namespace MyMauiApp.ViewModels;

        public class MainPageViewModel : INotifyPropertyChanged
        {
            private readonly Auth0Client _client;
            private string _name;
            private string _email;
            private bool _isAuthenticated;

            public event PropertyChangedEventHandler PropertyChanged;

            public string Name
            {
                get => _name;
                set { _name = value; OnPropertyChanged(); }
            }

            public string Email
            {
                get => _email;
                set { _email = value; OnPropertyChanged(); }
            }

            public bool IsAuthenticated
            {
                get => _isAuthenticated;
                set
                {
                    _isAuthenticated = value;
                    OnPropertyChanged();
                    OnPropertyChanged(nameof(IsNotAuthenticated));
                }
            }

            public bool IsNotAuthenticated => !IsAuthenticated;

            public ICommand LoginCommand { get; }
            public ICommand LogoutCommand { get; }

            public MainPageViewModel(Auth0Client client)
            {
                _client = client;
                LoginCommand = new Command(async () => await LoginAsync());
                LogoutCommand = new Command(async () => await LogoutAsync());
            }

            private async Task LoginAsync()
            {
                var loginResult = await _client.LoginAsync();

                if (loginResult.IsError)
                {
                    if (loginResult.Error == "UserCancel")
                        return; // ユーザーがブラウザーを閉じた場合。エラーではありません

                    await Shell.Current.DisplayAlert("Login failed", loginResult.Error, "OK");
                    return;
                }

                // ID トークンからユーザープロファイルのクレームを読み取る
                Name = loginResult.User.FindFirst(c => c.Type == "name")?.Value;
                Email = loginResult.User.FindFirst(c => c.Type == "email")?.Value;
                IsAuthenticated = true;
            }

            private async Task LogoutAsync()
            {
                await _client.LogoutAsync();

                Name = null;
                Email = null;
                IsAuthenticated = false;
            }

            private void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        ```
      </Tab>

      <Tab title="MainPage.xaml">
        `MainPage.xaml` で UI を構成します。

        ```xml MainPage.xaml lines theme={null}
        <?xml version="1.0" encoding="utf-8" ?>
        <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                     x:Class="MyMauiApp.MainPage">

            <VerticalStackLayout Spacing="20" Padding="30" VerticalOptions="Center">

                <!-- ログアウト時に表示 -->
                <Button Text="Log In"
                        Command="{Binding LoginCommand}"
                        IsVisible="{Binding IsNotAuthenticated}" />

                <!-- ログイン時に表示 -->
                <Label Text="{Binding Name, StringFormat='Welcome, {0}!'}"
                       IsVisible="{Binding IsAuthenticated}"
                       FontSize="24"
                       HorizontalOptions="Center" />

                <Label Text="{Binding Email}"
                       IsVisible="{Binding IsAuthenticated}"
                       HorizontalOptions="Center" />

                <Button Text="Log Out"
                        Command="{Binding LogoutCommand}"
                        IsVisible="{Binding IsAuthenticated}" />

            </VerticalStackLayout>
        </ContentPage>
        ```
      </Tab>

      <Tab title="MainPage.xaml.cs">
        `MainPage.xaml.cs` で BindingContext を設定します。

        ```csharp MainPage.xaml.cs lines theme={null}
        namespace MyMauiApp;

        public partial class MainPage : ContentPage
        {
            public MainPage(MainPageViewModel viewModel)
            {
                InitializeComponent();
                BindingContext = viewModel;
            }
        }
        ```
      </Tab>
    </Tabs>

    <Check>
      これでプロジェクトには、ログイン コマンドとログアウト コマンドを持つ ViewModel、データ バインドされた XAML ページ、それらを連携させるコードビハインドがそろいました。
    </Check>
  </Step>

  <Step title="サービスを登録し、Auth0 クライアントを初期化する" stepNumber={6}>
    次に、`MauiProgram.cs` で `Auth0Client`、ViewModel、ページを依存関係注入に登録します。これで各要素が連携され、Auth0クライアントが ViewModel に、ViewModel がページに注入されます。

    ```csharp MauiProgram.cs lines theme={null}
    using Auth0.OidcClient;
    using MyMauiApp.ViewModels;

    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                });

            // ステップ1の資格情報を使用してAuth0クライアントを設定する
            builder.Services.AddSingleton(new Auth0Client(new Auth0ClientOptions
            {
                Domain = "{yourDomain}",
                ClientId = "{yourClientId}",
                RedirectUri = "myapp://callback",
                PostLogoutRedirectUri = "myapp://callback"
            }));

            // ステップ5で作成したページとViewModelを登録する
            builder.Services.AddTransient<MainPage>();
            builder.Services.AddTransient<MainPageViewModel>();

            return builder.Build();
        }
    }
    ```

    `{yourDomain}` と `{yourClientId}` は、Auth0アプリケーションの設定値 (ステップ 1) に置き換えてください。
    MAUI アプリでは、`RedirectUri` と `PostLogoutRedirectUri` は **必須** です。Auth0 Dashboard で入力したものと同じコールバックURLを使用してください。
  </Step>

  <Step title="アプリを実行する" stepNumber={7}>
    .NET MAUI アプリケーションをビルドして実行する

    **想定される流れ:**

    1. アプリが起動し、**Log In** ボタンが表示される
    2. **Log In** をタップすると → システムブラウザーで Auth0 Universal Login が開く
    3. 認証を完了する (サインアップまたはログイン)
    4. ブラウザーからアプリにリダイレクトされる
    5. アプリに名前とメールアドレスが表示され、**Log Out** ボタンも表示される
  </Step>
</Steps>

<Check>
  これで、.NET MAUIアプリケーションでAuth0によるログイン機能を問題なく利用できるようになりました。
</Check>

***

<div id="troubleshooting">
  ## トラブルシューティング
</div>

<AccordionGroup>
  <Accordion title="コールバック URL の不一致">
    **症状**: ブラウザに「Callback URL mismatch. The provided redirect\_uri is not in the list of allowed callback URLs.」と表示されます。

    **修正方法:**

    1. コード内の **Client ID** が、Auth0 Dashboard で設定したアプリケーションのものと一致していることを確認します
    2. **Allowed Callback URLs** フィールドをクリアし、`myapp://callback` を手動で再入力します。コピー&ペーストすると、末尾に見えない空白や改行が入ることがあります
    3. 完全に一致していることを確認します。末尾のスラッシュなし、英小文字のみ、空白なしです
    4. Auth0 Dashboard で **Save Changes** を選択し、値が正しく保存されていることを確認します
    5. ブラウザのアドレスバーで `redirect_uri` クエリパラメータを確認し、アプリケーションが実際に何を送信しているかを確認します
  </Accordion>

  <Accordion title="Android: アプリがブラウザから戻らない">
    **症状**: login のためにブラウザは開きますが、アプリにリダイレクトされません。

    **修正方法:**

    1. `WebAuthenticatorActivity.cs` の `DataScheme` が `RedirectUri` のスキームと一致していることを確認します
    2. Activity に `Exported = true` が設定されていることを確認します
    3. Auth0 Dashboard の **Allowed Callback URLs** が完全に一致していることを確認します
  </Accordion>

  <Accordion title="Windows: login が止まったように見える">
    **症状**: ブラウザは開きますが、元のアプリに戻る代わりに 2 つ目のアプリ インスタンスが起動します。

    **修正方法:** `Platforms/Windows/App.xaml.cs` の `App` コンストラクターで、`Auth0.OidcClient.Platforms.Windows.Activator.Default.CheckRedirectionActivation()` が **最初の 1 行目** で呼び出されていること、および `Package.appxmanifest` のプロトコル名がコールバック URI スキームと一致していることを確認してください。
  </Accordion>

  <Accordion title="Windows: プロトコル アクティブ化が機能しない">
    **症状**: login 後、ブラウザにエラーが表示されるか何も起こらず、アプリがコールバックを受け取りません。

    **修正方法:** アプリは **パッケージ化された** (MSIX) アプリケーションである必要があります。`.csproj` ファイルに `<WindowsPackageType>` 要素があるか確認してください。

    * `None` に設定されている場合、プロトコル アクティブ化は利用できません。その行を削除するか、`<WindowsPackageType>MSIX</WindowsPackageType>` に変更してください。
    * 要素が存在しない場合、アプリは既定で既にパッケージ化されています。`Package.appxmanifest` に Step 4 の `<uap:Protocol>` 拡張が含まれていることを確認してください。
  </Accordion>

  <Accordion title="ユーザープロファイルにクレームがない">
    **症状**: `name`、`email`、または `picture` クレームが `loginResult.User` に含まれていません。

    **修正方法:** `openid profile email` が `Auth0ClientOptions.Scope` に含まれていることを確認します。スコープをカスタマイズしている場合は、`openid` が常に含まれていることを確認してください。
  </Accordion>
</AccordionGroup>

***

<div id="next-steps">
  ## 次のステップ
</div>

これで、.NET MAUI アプリで動作する Auth0 連携ができました。実装をさらに拡張するには、次のトピックを確認してください。

<Accordion title="リフレッシュトークン">
  Auth0 MAUI SDK はリフレッシュトークンをサポートしており、ユーザーに再入力を求めることなくセッションを自動更新できます。

  ### リフレッシュトークンを有効にする

  `Scope` プロパティに `offline_access` を追加します。

  ```csharp expandable lines theme={null}
  builder.Services.AddSingleton(new Auth0Client(new Auth0ClientOptions
  {
      Domain = "{yourDomain}",
      ClientId = "{yourClientId}",
      RedirectUri = "myapp://callback",
      PostLogoutRedirectUri = "myapp://callback",
      Scope = "openid profile email offline_access"
  }));
  ```

  ### リフレッシュトークンを使用する

  ログイン後にリフレッシュトークンを保存し、それを使ってセッションを自動更新します。

  ```csharp expandable lines theme={null}
  // ログイン後
  var refreshToken = loginResult.RefreshToken;

  // 後でセッションを更新
  var refreshResult = await _client.RefreshTokenAsync(refreshToken);

  if (!refreshResult.IsError)
  {
      var newAccessToken = refreshResult.AccessToken;
      var newIdToken = refreshResult.IdentityToken;
  }
  ```

  <Info>
    ログイン後に `RefreshToken` が `null` の場合は、Auth0 Dashboard の API 設定で **オフラインアクセスの許可** が有効になっていることを確認してください (`audience` パラメーターを使用している場合) 。
  </Info>
</Accordion>

<Accordion title="保護された API を呼び出す">
  API 用にスコープされたアクセストークンを取得するには、`Scope` を設定し、`audience` パラメーターを `LoginAsync()` に渡します。

  ```csharp expandable lines theme={null}
  var loginResult = await _client.LoginAsync(new
  {
      audience = "https://myapi.example.com"
  });

  // アクセストークンは API 用にスコープされます
  var accessToken = loginResult.AccessToken;

  var httpClient = new HttpClient();
  httpClient.DefaultRequestHeaders.Authorization =
      new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);

  var response = await httpClient.GetAsync("https://myapi.example.com/posts");
  ```
</Accordion>

<Accordion title="Organizations (B2B/enterprise)">
  特定の Auth0 Organization 内でユーザーを認証します。

  ```csharp expandable lines theme={null}
  var loginResult = await _client.LoginAsync(new
  {
      organization = "org_abc123"
  });
  ```

  詳しくは、[Organizations](/docs/ja-jp/manage-users/organizations) を参照してください。
</Accordion>

<Accordion title="再認証を強制する">
  指定した時間が経過した後に再認証を強制するには、`MaxAge` を使用します。

  ```csharp expandable lines theme={null}
  new Auth0ClientOptions
  {
      Domain = "{yourDomain}",
      ClientId = "{yourClientId}",
      RedirectUri = "myapp://callback",
      PostLogoutRedirectUri = "myapp://callback",
      MaxAge = TimeSpan.FromMinutes(30)
  }
  ```
</Accordion>

<Accordion title="Universal Login をカスタマイズする">
  色、ロゴ、テキストなどを含めて、Auth0 のログインページをブランドに合わせて調整できます。

  詳しくは、[Universal Login をカスタマイズする](/docs/ja-jp/customize/universal-login-pages) を参照してください。
</Accordion>

***

<div id="additional-resources">
  ## 追加リソース
</div>

<CardGroup cols={3}>
  <Card title="SDK リポジトリ" icon="github" href="https://github.com/auth0/auth0-oidc-client-net">
    ソースコード、サンプル、API リファレンス
  </Card>

  <Card title="Token Best Practices" icon="key" href="/docs/ja-jp/secure/tokens/token-best-practices">
    トークンのセキュリティに関するベストプラクティス
  </Card>

  <Card title="PKCE フロー" icon="shield" href="/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce">
    ネイティブアプリが安全に認証を行う方法
  </Card>

  <Card title="コミュニティフォーラム" icon="comments" href="https://community.auth0.com/">
    Auth0 コミュニティからサポートを受ける
  </Card>
</CardGroup>
