plugins/auth0/skills/auth0-wpf/SKILL.md
Use when adding Auth0 authentication to WPF (Windows Presentation Foundation) desktop applications - integrates Auth0.OidcClient.WPF NuGet package for native login, logout, token refresh, and user profile. Trigger on WPF authentication, add login to WPF, Auth0 WPF, .NET WPF auth, Windows desktop auth
npx skillsauth add auth0/agent-skills auth0-wpfInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Add Auth0 authentication to WPF (Windows Presentation Foundation) desktop applications. This skill integrates the Auth0.OidcClient.WPF NuGet package which uses WebView2 to display the Auth0 login page in a popup window 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 WPF Window. Unlike native mobile SDKs that require URL scheme registration in Info.plist or AndroidManifest.xml, the WPF 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("wpf-")) | .tag_name | ltrimstr("wpf-")] | .[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 |
| Windows Forms desktop app | auth0-winforms |
| 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.WPFAuth0Client initialization and wire login/logout to XAML 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 window — 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, WPF 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 WPF 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.WPF 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 | WPF 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 window (WebAuth flow with PKCE)
var loginResult = await client.LoginAsync();
if (!loginResult.IsError)
{
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}");
}
}
// Store the refresh token from login for later use
var refreshToken = loginResult.RefreshToken;
// Logout
await client.LogoutAsync();
// Refresh token (requires offline_access scope)
var refreshResult = await client.RefreshTokenAsync(refreshToken);
if (refreshResult.IsError == false)
{
var newAccessToken = refreshResult.AccessToken;
}
<Window x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Auth0 WPF App" Height="450" Width="800">
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button x:Name="LoginButton" Content="Login" Width="200" Height="40"
Margin="10" Click="LoginButton_Click" FontSize="16"/>
<Button x:Name="LogoutButton" Content="Logout" Width="200" Height="40"
Margin="10" Click="LogoutButton_Click" FontSize="16"/>
</StackPanel>
</Grid>
</Window>
using Auth0.OidcClient;
using System.Diagnostics;
namespace MyApp;
public partial class MainWindow : Window
{
private Auth0Client _client;
public MainWindow()
{
InitializeComponent();
_client = new Auth0Client(new Auth0ClientOptions
{
Domain = "{yourDomain}",
ClientId = "{yourClientId}",
Scope = "openid profile email offline_access"
});
}
private async void LoginButton_Click(object sender, RoutedEventArgs e)
{
var loginResult = await _client.LoginAsync();
if (loginResult.IsError)
{
Debug.WriteLine($"An error occurred during login: {loginResult.Error}");
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, RoutedEventArgs e)
{
await _client.LogoutAsync();
}
}
development
Use when adding login, logout, and user profile to a Laravel web application using session-based authentication - integrates auth0/login (laravel-auth0) for guard-based auth with auto-registered routes.
tools
Use when securing Laravel API endpoints with JWT Bearer token validation, scope/permission checks, or stateless auth - integrates auth0/login (laravel-auth0) with the AuthorizationGuard for REST APIs receiving access tokens from SPAs, mobile apps, or other clients. Triggers on: Laravel API auth, auth0.authorizer, AuthorizationGuard, Laravel JWT, stateless Bearer.
development
Use when adding Auth0 authentication to a Flutter web application — integrates the auth0_flutter SDK (web platform) for browser-based authentication using redirect login, popup login, and credential caching.
development
Use when adding Auth0 authentication to a Flutter mobile application (iOS/Android) — integrates the auth0_flutter SDK (native platform) for Web Auth login/logout via the system browser, with secure credential storage and biometric protection through the CredentialsManager.