次のような場合に使用: Windows Forms(Windowsデスクトップアプリケーション用のフレームワーク)を使ったアプリケーションにAuth0(クラウド認証サービス)のログイン、ログアウト、またはトークン(本人確認用の暗号化された情報)管理機能を追加する場合。Auth0.OidcClient.WinForms(この機能の連携用ライブラリ)を統合します。ユーザーが「WinFormsアプリにログイン機能を追加したい」や「WindowsデスクトップアプリにAuth0を追加したい」と言った場合でも、このスキルを使用してください。
Use when adding Auth0 login, logout, or token management to a Windows Forms (WinForms) desktop application. Integrates Auth0.OidcClient.WinForms — use even if the user says "add login to my WinForms app" or "add Auth0 to my Windows desktop app".
Windows Forms(WinForms)デスクトップアプリケーションに Auth0 認証を追加します。
このスキルは Auth0.OidcClient.WinForms NuGet パッケージを統合します。
WebView2 を使用して Auth0 ログインページをポップアップフォーム内に表示し、PKCE を用いた OIDC ベースのセキュアなログイン・ログアウトフローを実現します。
SDK は、WinForms の Form にホストされた WebView2 コントロール内で Auth0 Universal Login ページを開くことにより、WebAuth(PKCE 付き OIDC 認可コードフロー)を実行します。 Info.plist や AndroidManifest.xml への URL スキーム登録が必要なネイティブモバイル SDK とは異なり、WinForms SDK はコールバックを WebView2 のナビゲーションイベント内で完結して処理します。カスタム URL タイプやプロトコルハンドラーは不要です。
Agent への指示: SDK のセットアップ手順を提供する前に、以下のコマンドを実行して最新リリースバージョンを取得してください:
gh api repos/auth0/auth0-oidc-client-net/releases --jq '[.[] | select(.tag_name | startswith("winforms-")) | .tag_name | ltrimstr("winforms-")] | .[0]'以下に記載されているハードコードされたバージョンの代わりに、返却されたバージョンをすべての依存関係行で使用してください。
| ユースケース | 推奨スキル |
|---|---|
| .NET MAUI クロスプラットフォームアプリ | auth0-maui |
| WPF デスクトップアプリ | auth0-wpf |
| ASP.NET Core サーバーサイド Web アプリ | auth0-aspnetcore-authentication |
| ASP.NET Core Web API(JWT 検証) | auth0-aspnetcore-api |
| iOS 専用 Swift アプリ | auth0-swift |
| Android 専用 Kotlin アプリ | auth0-android |
Agent への指示: 開始前に、ユーザーのプロジェクトを確認してください:
.csprojファイルのTargetFrameworkから .NET バージョンを特定する- コードベースに既存の認証プロバイダーがないか確認する — 既存の
Auth0ClientまたはWebViewBrowserの使用箇所を検索し、見つかった場合は再利用する- プロジェクトの名前空間とディレクトリの規則を把握する
dotnet add package Auth0.OidcClient.WinFormsAuth0Client の初期化を追加し、ログイン/ログアウトをボタンのクリックハンドラーに接続します。dotnet buildAgent への指示: Auth0Client の設定を記述する際は以下に注意してください:
- このスキルのインテグレーションガイドに記載された正確なコードパターンを使用すること。
- SDK は WebView2 を使用してログインページをポップアップフォームに表示します — カスタムブラウザのセットアップは不要です。
- デフォルトのコールバック URL は
https://{yourDomain}/mobileです — Auth0 ダッシュボードの Allowed Callback URLs および Allowed Logout URLs に追加する必要があります。https://{domain}/ios/{bundleId}/callbackのようなプラットフォーム固有のパターンを使用するネイティブモバイル SDK とは異なり、WinForms はよりシンプルなhttps://{domain}/mobileコールバック形式を使用します。設定とコードの記述後、ビルドが成功することを確認してください:
dotnet buildビルドが失敗した場合は問題の修正を試みてください。5〜6 回試みても失敗する場合は、ユーザーに助けを求めてください。
WinForms SDK はデフォルトのコールバック URL として https://{yourDomain}/mobile を使用します。
これはモバイルネイティブ SDK とは異なります:
https://{domain}/ios/{bundleId}/callback や https://{domain}/android/{packageName}/callback のようなプラットフォーム固有のコールバックを使用しますhttps://{yourDomain}/mobile コールバックを使用しますコールバックは WebView2 コントロールの NavigationStarting イベントによってインターセプトされます。システムレベルの URL スキーム登録は不要です。
Info.plist、AndroidManifest.xml、Windows プロトコルハンドラーの設定は一切不要です。
Auth0 ダッシュボードで以下を設定してください:
https://{yourDomain}/mobilehttps://{yourDomain}/mobileAuth0.OidcClient.WinForms パッケージがインストール済みAuth0Client に Domain と ClientId が設定済みhttps://{yourDomain}/mobile が Auth0 ダッシュボードに登録済みAuth0ClientOptions の完全リファレンス、クレーム、テストチェックリスト、トラブルシューティング| 間違い | 修正方法 |
|---|---|
| Auth0 ダッシュボードでアプリタイプが Native に設定されていない | ダッシュボードの設定でアプリケーションタイプを「Native」に変更する |
| Auth0 ダッシュボードにコールバック URL が未登録 | https://{yourDomain}/mobile を Allowed Callback URLs と Allowed Logout URLs の両方に追加する |
Domain の設定に https:// プレフィックスを使用している |
Domain はホスト名のみを指定する(例: tenant.auth0.com。https://tenant.auth0.com は不可) |
| WebView2 ランタイムがインストールされていない | Windows 10 に Microsoft Edge WebView2 ランタイムをインストールする(Windows 11 には同梱) |
トークンリフレッシュに必要な offline_access スコープが未指定 |
Auth0ClientOptions の Scope に offline_access を追加する |
| コード内に ClientSecret を保存している | ネイティブアプリは Client Secret を使用しません — 削除してください |
| レジストリ/マニフェストへの URL スキーム登録を試みている | WinForms は WebView2 をインプロセスで使用するため、URL スキームの登録は不要(AppxManifest が必要な MAUI とは異なる) |
Agent への指示: 物理デバイスでのテストをユーザーに促してください。WebView2 の一部の動作(ポップアップウィンドウ、証明書の処理など)は、リモートデスクトップや仮想マシン環境と物理 Windows マシンで異なる場合があります。リリース前に、実際のハードウェアでログイン → WebView2 → コールバック → トークン取得の完全なフローをテストしてください。
テストチェックリスト:
RefreshTokenAsync が動作するUserCancel を適切に処理するusing Auth0.OidcClient;
using System.Diagnostics;
// クライアントの初期化
var client = new Auth0Client(new Auth0ClientOptions
{
Domain = "{yourDomain}",
ClientId = "{yourClientId}",
Scope = "openid profile email offline_access"
});
// ログイン — WebView2 ポップアップフォームを開く(PKCE 付き WebAuth フロー)
var loginResult = await client.LoginAsync();
if (loginResult.IsError == false)
{
var user = loginResult.User;
var name = user.FindFirst(c => c.Type == "name")?.Value;
var email = user.FindFirst(c => c.Type == "email")?.Value;
var picture = user.FindFirst(c => c.Type == "picture")?.Value;
Debug.WriteLine($"name: {name}");
Debug.WriteLine($"email: {email}");
foreach (var claim in loginResult.User.Claims)
{
Debug.WriteLine($"{claim.Type} = {claim.Value}");
}
}
// ログアウト
await client.LogoutAsync();
// トークンリフレッシュ(offline_access スコープが必要)
var refreshToken = loginResult.RefreshToken;
var refreshResult = await client.RefreshTokenAsync(refreshToken);
if (refreshResult.IsError == false)
{
var newAccessToken = refreshResult.AccessToken;
}
using Auth0.OidcClient;
using System.Diagnostics;
namespace MyApp;
public partial class Form1 : Form
{
private Auth0Client _client;
private Button loginButton;
private Button logoutButton;
public Form1()
{
InitializeComponent();
_client = new Auth0Client(new Auth0ClientOptions
{
Domain = "{yourDomain}",
ClientId = "{yourClientId}",
Scope = "openid profile email offline_access"
});
loginButton = new Button
{
Text = "Log In",
Width = 120,
Height = 40,
Left = (ClientSize.Width - 120) / 2,
Top = (ClientSize.Height - 40) / 2
};
loginButton.Click += loginButton_Click;
Controls.Add(loginButton);
logoutButton = new Button
{
Text = "Log Out",
Width = 120,
Height = 40,
Left = (ClientSize.Width - 120) / 2,
Top = (ClientSize.Height - 40) / 2 + 50
};
logoutButton.Click += logoutButton_Click;
Controls.Add(logoutButton);
}
private async void loginButton_Click(object sender, EventArgs e)
{
var loginResult = await _client.LoginAsync();
if (loginResult.IsError)
{
Debug.WriteLine($"Error: {loginResult.Error}");
Debug.WriteLine($"Description: {loginResult.ErrorDescription}");
return;
}
var user = loginResult.User;
var name = user.FindFirst(c => c.Type == "name")?.Value;
var email = user.FindFirst(c => c.Type == "email")?.Value;
var picture = user.FindFirst(c => c.Type == "picture")?.Value;
Debug.WriteLine($"name: {name}");
Debug.WriteLine($"email: {email}");
foreach (var claim in loginResult.User.Claims
Add Auth0 authentication to Windows Forms (WinForms) desktop applications. This skill integrates the Auth0.OidcClient.WinForms NuGet package which uses WebView2 to display the Auth0 login page in a popup form for secure OIDC-based login and logout flows with PKCE.
The SDK performs WebAuth (OIDC authorization code flow with PKCE) by opening the Auth0 Universal Login page inside a WebView2 control hosted in a WinForms Form. Unlike native mobile SDKs that require URL scheme registration in Info.plist or AndroidManifest.xml, the WinForms SDK handles the callback entirely within the WebView2 navigation events — no custom URL Types or protocol handlers are needed.
Agent instruction: Before providing SDK setup instructions, fetch the latest release version by running:
gh api repos/auth0/auth0-oidc-client-net/releases --jq '[.[] | select(.tag_name | startswith("winforms-")) | .tag_name | ltrimstr("winforms-")] | .[0]'Use the returned version in all dependency lines instead of any hardcoded version below.
| Use Case | Recommended Skill |
|---|---|
| .NET MAUI cross-platform app | auth0-maui |
| WPF desktop app | auth0-wpf |
| ASP.NET Core server-side web app | auth0-aspnetcore-authentication |
| ASP.NET Core Web API (JWT validation) | auth0-aspnetcore-api |
| iOS-only Swift app | auth0-swift |
| Android-only Kotlin app | auth0-android |
Agent instruction: Before starting, examine the user's project:
- Identify the .NET version from the
.csprojfile (TargetFramework)- Check if there is already an existing authentication provider in the codebase — search for existing
Auth0ClientorWebViewBrowserusage and reuse if found- Note the project's namespace and directory conventions
dotnet add package Auth0.OidcClient.WinFormsAuth0Client initialization and wire login/logout to button click handlers.dotnet buildAgent instruction: When writing the Auth0Client configuration:
- Use the exact code patterns from this skill's integration guide.
- The SDK uses WebView2 to show the login page in a popup form — no custom browser setup needed.
- The default callback URL is
https://{yourDomain}/mobile— this must be added to Auth0 Dashboard Allowed Callback URLs and Allowed Logout URLs.- Unlike native mobile SDKs that use
https://{domain}/ios/{bundleId}/callbackor similar platform-specific patterns, WinForms uses the simplerhttps://{domain}/mobilecallback format.After writing configuration and code, verify the build succeeds:
dotnet buildIf the build fails, attempt to fix the issue. After 5-6 failed attempts, ask the user for help.
The WinForms SDK uses https://{yourDomain}/mobile as its default callback URL. This differs from mobile native SDKs:
https://{domain}/ios/{bundleId}/callback or https://{domain}/android/{packageName}/callbackhttps://{yourDomain}/mobile callbackThe callback is intercepted by the WebView2 control's NavigationStarting event — no system-level URL scheme registration is required. You do NOT need to configure Info.plist, AndroidManifest.xml, or Windows protocol handlers.
Configure in the Auth0 Dashboard:
https://{yourDomain}/mobilehttps://{yourDomain}/mobileAuth0.OidcClient.WinForms package installedAuth0Client configured with Domain and ClientIdhttps://{yourDomain}/mobile registered in Auth0 DashboardAuth0ClientOptions reference, claims, testing checklist, troubleshooting| Mistake | Fix |
|---|---|
| App type not set to Native in Auth0 Dashboard | Change application type to "Native" in Dashboard settings |
| Missing callback URL in Auth0 Dashboard | Add https://{yourDomain}/mobile to both Allowed Callback URLs AND Allowed Logout URLs |
Using https:// prefix in Domain config |
Domain should be hostname only (e.g., tenant.auth0.com, not https://tenant.auth0.com) |
| WebView2 Runtime not installed | Install Microsoft Edge WebView2 Runtime on Windows 10 (included with Windows 11) |
Not requesting offline_access scope for token refresh |
Add offline_access to Scope in Auth0ClientOptions |
| Storing ClientSecret in code | Native apps do NOT use a Client Secret — remove it |
| Trying to register URL scheme in registry/manifest | WinForms uses WebView2 in-process — no URL scheme registration needed (unlike MAUI which needs AppxManifest) |
Agent instruction: Remind the user to test on a physical device. Some WebView2 behaviors (popup windows, certificate handling) may differ in remote desktop or virtual machine environments vs. physical Windows machines. Test the full login → WebView2 → callback → token flow on real hardware before shipping.
Testing Checklist:
RefreshTokenAsync with stored refresh token worksUserCancel gracefullyusing Auth0.OidcClient;
using System.Diagnostics;
// Initialize client
var client = new Auth0Client(new Auth0ClientOptions
{
Domain = "{yourDomain}",
ClientId = "{yourClientId}",
Scope = "openid profile email offline_access"
});
// Login — opens WebView2 popup form (WebAuth flow with PKCE)
var loginResult = await client.LoginAsync();
if (loginResult.IsError == false)
{
var user = loginResult.User;
var name = user.FindFirst(c => c.Type == "name")?.Value;
var email = user.FindFirst(c => c.Type == "email")?.Value;
var picture = user.FindFirst(c => c.Type == "picture")?.Value;
Debug.WriteLine($"name: {name}");
Debug.WriteLine($"email: {email}");
foreach (var claim in loginResult.User.Claims)
{
Debug.WriteLine($"{claim.Type} = {claim.Value}");
}
}
// Logout
await client.LogoutAsync();
// Refresh token (requires offline_access scope)
var refreshToken = loginResult.RefreshToken;
var refreshResult = await client.RefreshTokenAsync(refreshToken);
if (refreshResult.IsError == false)
{
var newAccessToken = refreshResult.AccessToken;
}
using Auth0.OidcClient;
using System.Diagnostics;
namespace MyApp;
public partial class Form1 : Form
{
private Auth0Client _client;
private Button loginButton;
private Button logoutButton;
public Form1()
{
InitializeComponent();
_client = new Auth0Client(new Auth0ClientOptions
{
Domain = "{yourDomain}",
ClientId = "{yourClientId}",
Scope = "openid profile email offline_access"
});
loginButton = new Button
{
Text = "Log In",
Width = 120,
Height = 40,
Left = (ClientSize.Width - 120) / 2,
Top = (ClientSize.Height - 40) / 2
};
loginButton.Click += loginButton_Click;
Controls.Add(loginButton);
logoutButton = new Button
{
Text = "Log Out",
Width = 120,
Height = 40,
Left = (ClientSize.Width - 120) / 2,
Top = (ClientSize.Height - 40) / 2 + 50
};
logoutButton.Click += logoutButton_Click;
Controls.Add(logoutButton);
}
private async void loginButton_Click(object sender, EventArgs e)
{
var loginResult = await _client.LoginAsync();
if (loginResult.IsError)
{
Debug.WriteLine($"Error: {loginResult.Error}");
Debug.WriteLine($"Description: {loginResult.ErrorDescription}");
return;
}
var user = loginResult.User;
var name = user.FindFirst(c => c.Type == "name")?.Value;
var email = user.FindFirst(c => c.Type == "email")?.Value;
var picture = user.FindFirst(c => c.Type == "picture")?.Value;
Debug.WriteLine($"name: {name}");
Debug.WriteLine($"email: {email}");
foreach (var claim in loginResult.User.Claims)
{
Debug.WriteLine($"{claim.Type} = {claim.Value}");
}
}
private async void logoutButton_Click(object sender, EventArgs e)
{
await _client.LogoutAsync();
}
}
原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。