Intégration Auth0 WPF
Ajoutez l'authentification Auth0 aux applications de bureau WPF (Windows Presentation Foundation). Cette skill intègre le package NuGet Auth0.OidcClient.WPF qui utilise WebView2 pour afficher la page de connexion Auth0 dans une fenêtre popup pour des flux de connexion et déconnexion sécurisés basés sur OIDC avec PKCE.
Le SDK effectue une WebAuth (flux de code d'autorisation OIDC avec PKCE) en ouvrant la page Auth0 Universal Login à l'intérieur d'un contrôle WebView2 hébergé dans une fenêtre WPF. Contrairement aux SDK mobiles natifs qui nécessitent une inscription de schéma URL dans Info.plist ou AndroidManifest.xml, le SDK WPF gère le callback entièrement dans les événements de navigation WebView2 — aucun URL Type personnalisé ou gestionnaire de protocole n'est nécessaire.
Instruction pour l'agent : Avant de fournir les instructions de configuration du SDK, récupérez la dernière version de release en exécutant :
gh api repos/auth0/auth0-oidc-client-net/releases --jq '[.[] | select(.tag_name | startswith("wpf-")) | .tag_name | ltrimstr("wpf-")] | .[0]'Utilisez la version retournée dans toutes les lignes de dépendances au lieu de toute version codée en dur ci-dessous.
Prérequis
- SDK .NET 6.0 ou ultérieur (WPF nécessite Windows)
- Visual Studio 2022 ou JetBrains Rider avec la charge de travail de développement de bureau .NET
- Windows 10 ou ultérieur
- Runtime Microsoft Edge WebView2 (inclus avec Windows 11, installable sur Windows 10)
- Compte Auth0 avec une application Native configurée
- Node.js 20+ (pour la configuration automatisée Auth0 CLI)
Quand NE PAS utiliser
| Cas d'usage | Skill recommandée |
|---|---|
| Application .NET MAUI multiplateforme | auth0-maui |
| Application de bureau Windows Forms | auth0-winforms |
| Application web ASP.NET Core côté serveur | auth0-aspnetcore-authentication |
| Web API ASP.NET Core (validation JWT) | auth0-aspnetcore-api |
| Application Swift iOS uniquement | auth0-swift |
| Application Kotlin Android uniquement | auth0-android |
Workflow de démarrage rapide
Instruction pour l'agent : Avant de commencer, examinez le projet de l'utilisateur :
- Identifiez la version .NET depuis le fichier
.csproj(TargetFramework)- Vérifiez s'il existe déjà un fournisseur d'authentification dans le code — recherchez une utilisation existante de
Auth0ClientouWebViewBrowseret réutilisez si trouvé- Notez l'espace de noms du projet et les conventions de répertoires
- Installer le SDK :
dotnet add package Auth0.OidcClient.WPF - Configurer Auth0 : Voir Setup Guide pour une configuration automatique ou manuelle.
- Intégrer l'authentification : Ajoutez l'initialisation
Auth0Clientet connectez la connexion/déconnexion aux gestionnaires de clic des boutons XAML. - Compiler et vérifier :
dotnet build
Instruction pour l'agent : Lors de la rédaction de la configuration
Auth0Client:
- Utilisez les patterns de code exacts du guide d'intégration de cette skill.
- Le SDK utilise WebView2 pour afficher la page de connexion dans une fenêtre popup — aucune configuration de navigateur personnalisée nécessaire.
- L'URL de callback par défaut est
https://{yourDomain}/mobile— elle doit être ajoutée aux URLs de callback autorisées et URLs de déconnexion autorisées du tableau de bord Auth0.- Contrairement aux SDK mobiles natifs qui utilisent
https://{domain}/ios/{bundleId}/callbackou des patterns spécifiques à la plateforme similaires, WPF utilise le format de callback plus simplehttps://{domain}/mobile.Après avoir écrit la configuration et le code, vérifiez que la compilation réussit :
dotnet buildSi la compilation échoue, tentez de corriger le problème. Après 5-6 tentatives échouées, demandez de l'aide à l'utilisateur.
Configuration de l'URL de callback
Le SDK WPF utilise https://{yourDomain}/mobile comme URL de callback par défaut. Cela diffère des SDK mobiles natifs :
- SDK mobiles utilisent des callbacks spécifiques à la plateforme comme
https://{domain}/ios/{bundleId}/callbackouhttps://{domain}/android/{packageName}/callback - WPF/WinForms utilisent le callback générique
https://{yourDomain}/mobile
Le callback est intercepté par l'événement NavigationStarting du contrôle WebView2 — aucune inscription de schéma URL au niveau du système n'est requise. Vous N'AVEZ PAS besoin de configurer Info.plist, AndroidManifest.xml ou des gestionnaires de protocole Windows.
Configurez dans le tableau de bord Auth0 :
- URLs de callback autorisées :
https://{yourDomain}/mobile - URLs de déconnexion autorisées :
https://{yourDomain}/mobile
C'est terminé quand
- [ ] Package
Auth0.OidcClient.WPFinstallé - [ ]
Auth0Clientconfiguré avec Domain et ClientId - [ ] Flux de connexion/déconnexion fonctionnant (popup WebView2 s'ouvre pour l'authentification)
- [ ] Affirmations du profil utilisateur accessibles après connexion
- [ ] URL de callback
https://{yourDomain}/mobileenregistrée dans le tableau de bord Auth0 - [ ] La compilation réussit sans erreurs
- [ ] Testé sur appareil réel (machine Windows physique, pas seulement bureau à distance)
Documentation détaillée
- Setup Guide — Configuration du tenant Auth0, installation du SDK, configuration de l'URL de callback
- Integration Patterns — Flux de connexion/déconnexion, rafraîchissement de token, profil utilisateur, gestion des erreurs
- API Reference & Testing — Référence complète
Auth0ClientOptions, affirmations, liste de vérification de test, dépannage
Erreurs courantes
| Erreur | Correctif |
|---|---|
| Type d'app non défini sur Native dans le tableau de bord Auth0 | Changez le type d'application en "Native" dans les paramètres du tableau de bord |
| URL de callback manquante dans le tableau de bord Auth0 | Ajoutez https://{yourDomain}/mobile à la fois aux URLs de callback autorisées ET aux URLs de déconnexion autorisées |
Utilisation du préfixe https:// dans la configuration du Domain |
Le Domain doit être le nom d'hôte uniquement (ex. tenant.auth0.com, pas https://tenant.auth0.com) |
| Runtime WebView2 non installé | Installez Microsoft Edge WebView2 Runtime sur Windows 10 (inclus avec Windows 11) |
Non demande du scope offline_access pour le rafraîchissement de token |
Ajoutez offline_access à Scope dans Auth0ClientOptions |
| Stockage du ClientSecret dans le code | Les applications natives N'UTILISENT PAS de Client Secret — supprimez-le |
| Tentative d'inscription du schéma URL dans le registre/manifest | WPF utilise WebView2 en processus — aucune inscription de schéma URL nécessaire (contrairement à MAUI qui nécessite AppxManifest) |
Notes de test
Instruction pour l'agent : Rappelez à l'utilisateur de tester sur un appareil physique. Certains comportements WebView2 (fenêtres popup, gestion des certificats) peuvent différer dans les environnements de bureau à distance ou de machine virtuelle par rapport aux machines Windows physiques. Testez le flux complet connexion → WebView2 → callback → token sur du matériel réel avant de déployer.
Liste de vérification de test :
- Flux de connexion : Cliquez sur connexion → popup WebView2 s'ouvre → authentification → popup se ferme → infos utilisateur affichées
- Flux de déconnexion : Cliquez sur déconnexion → popup WebView2 s'ouvre → session effacée → popup se ferme
- Rafraîchissement de token :
RefreshTokenAsyncavec refresh token stocké fonctionne - Annulation : L'utilisateur ferme la fenêtre WebView2 → l'app gère
UserCancelcorrectement - Appareil physique : Testez sur une vraie machine Windows (pas seulement un environnement virtuel)
- Connexions multiples : Vérifiez que la connexion fonctionne après la déconnexion (pas d'état obsolète)
Skills connexes
- auth0-winforms — Applications de bureau Windows Forms
- auth0-maui — Applications multiplateforme .NET MAUI
- auth0-aspnetcore-authentication — Applications web ASP.NET Core côté serveur
- auth0-aspnetcore-api — Web API ASP.NET Core avec validation JWT
Référence rapide
using Auth0.OidcClient;
using System.Diagnostics;
// Initialiser le client
var client = new Auth0Client(new Auth0ClientOptions
{
Domain = "{yourDomain}",
ClientId = "{yourClientId}",
Scope = "openid profile email offline_access"
});
// Connexion — ouvre la fenêtre popup WebView2 (flux WebAuth avec 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}");
}
}
// Stocker le refresh token depuis la connexion pour une utilisation ultérieure
var refreshToken = loginResult.RefreshToken;
// Déconnexion
await client.LogoutAsync();
// Rafraîchir le token (nécessite le scope offline_access)
var refreshResult = await client.RefreshTokenAsync(refreshToken);
if (refreshResult.IsError == false)
{
var newAccessToken = refreshResult.AccessToken;
}
MainWindow.xaml (UI WPF)
<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>
MainWindow.xaml.cs (Code-Behind WPF)
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();
}
}