Intégration Auth0 WinForms
Ajoutez l'authentification Auth0 aux applications desktop Windows Forms (WinForms). Cette skill intègre le package NuGet Auth0.OidcClient.WinForms qui utilise WebView2 pour afficher la page de connexion Auth0 dans un formulaire popup, permettant des flux de login et logout sécurisés basés sur OIDC avec PKCE.
Le SDK effectue une WebAuth (flux du code d'autorisation OIDC avec PKCE) en ouvrant la page Auth0 Universal Login à l'intérieur d'un contrôle WebView2 hébergé dans un Form WinForms. Contrairement aux SDK mobiles natifs qui nécessitent l'enregistrement d'un schéma d'URL dans Info.plist ou AndroidManifest.xml, le SDK WinForms gère le rappel entièrement via les événements de navigation WebView2 — aucun type d'URL personnalisé ni gestionnaire de protocole n'est requis.
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("winforms-")) | .tag_name | ltrimstr("winforms-")] | .[0]'Utilisez la version retournée dans toutes les lignes de dépendances au lieu de toute version en dur ci-dessous.
Prérequis
- SDK .NET 6.0 ou ultérieur (WinForms nécessite Windows)
- Visual Studio 2022 ou JetBrains Rider avec la charge de travail de développement desktop .NET
- Windows 10 ou ultérieur
- Microsoft Edge WebView2 Runtime (inclus avec Windows 11, installable sur Windows 10)
- Compte Auth0 avec une application Native configurée
- Node.js 20+ (pour la configuration automatisée avec Auth0 CLI)
Quand NE PAS utiliser
| Cas d'usage | Skill recommandée |
|---|---|
| Application .NET MAUI multiplateforme | auth0-maui |
| Application desktop WPF | auth0-wpf |
| Application web côté serveur ASP.NET Core | 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 |
Flux de démarrage rapide
Instruction pour l'agent : Avant de commencer, examinez le projet de l'utilisateur :
- Identifiez la version .NET à partir du fichier
.csproj(TargetFramework)- Vérifiez s'il existe déjà un fournisseur d'authentification dans la base de code — cherchez l'utilisation existante de
Auth0ClientouWebViewBrowseret réutilisez-la si présente- Notez les conventions d'espace de noms et de répertoires du projet
- Installer le SDK :
dotnet add package Auth0.OidcClient.WinForms - Configurer Auth0 : Voir le Guide de configuration pour une configuration automatique ou manuelle.
- Intégrer l'authentification : Ajoutez l'initialisation de
Auth0Clientet reliez login/logout aux gestionnaires de clics de bouton. - Compiler et vérifier :
dotnet build
Instruction pour l'agent : Lors de l'écriture de la configuration Auth0Client :
- Utilisez les motifs de code exacts du guide d'intégration de cette skill.
- Le SDK utilise WebView2 pour afficher la page de connexion dans un formulaire popup — aucune configuration de navigateur personnalisée n'est nécessaire.
- L'URL de rappel par défaut est
https://{yourDomain}/mobile— elle doit être ajoutée aux URLs de rappel autorisées et aux URLs de déconnexion autorisées du tableau de bord Auth0.- Contrairement aux SDK mobiles natifs qui utilisent
https://{domain}/ios/{bundleId}/callbackou des motifs spécifiques à la plateforme similaires, WinForms utilise le format de rappel 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, essayez de corriger le problème. Après 5-6 tentatives échouées, demandez de l'aide à l'utilisateur.
Configuration de l'URL de rappel
Le SDK WinForms utilise https://{yourDomain}/mobile comme URL de rappel par défaut. Cela diffère des SDK mobiles natifs :
- SDK mobiles utilisent des rappels spécifiques à la plateforme comme
https://{domain}/ios/{bundleId}/callbackouhttps://{domain}/android/{packageName}/callback - WPF/WinForms utilisent le rappel générique
https://{yourDomain}/mobile
Le rappel est intercepté par l'événement NavigationStarting du contrôle WebView2 — aucun enregistrement d'URL scheme au niveau du système n'est requis. 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 rappel autorisées :
https://{yourDomain}/mobile - URLs de déconnexion autorisées :
https://{yourDomain}/mobile
Terminé quand
- [ ] Package
Auth0.OidcClient.WinFormsinstallé - [ ]
Auth0Clientconfiguré avec Domain et ClientId - [ ] Flux de login/logout fonctionnant (le popup WebView2 s'ouvre pour l'authentification)
- [ ] Les revendications du profil utilisateur sont accessibles après la connexion
- [ ] URL de rappel
https://{yourDomain}/mobileenregistrée dans le tableau de bord Auth0 - [ ] La compilation réussit sans erreurs
- [ ] Testé sur un appareil réel (machine Windows physique, pas seulement un bureau distant)
Documentation détaillée
- Guide de configuration — Configuration du locataire Auth0, installation du SDK, configuration de l'URL de rappel
- Motifs d'intégration — Flux de login/logout, rafraîchissement des tokens, profil utilisateur, gestion des erreurs
- Référence API et tests — Référence complète de
Auth0ClientOptions, revendications, checklist de test, dépannage
Erreurs courantes
| Erreur | Correction |
|---|---|
| Type d'app non défini sur Native dans le tableau de bord Auth0 | Changez le type d'application à « Native » dans les paramètres du tableau de bord |
| URL de rappel manquante dans le tableau de bord Auth0 | Ajoutez https://{yourDomain}/mobile à la fois aux URLs de rappel autorisées ET aux URLs de déconnexion autorisées |
Utilisation du préfixe https:// dans la configuration Domain |
Domain doit être le seul nom d'hôte (par ex., tenant.auth0.com, pas https://tenant.auth0.com) |
| WebView2 Runtime non installé | Installez Microsoft Edge WebView2 Runtime sur Windows 10 (inclus avec Windows 11) |
Non-demande de la portée offline_access pour le rafraîchissement des tokens |
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'enregistrement du schéma d'URL dans le registre/manifest | WinForms utilise WebView2 en processus — aucun enregistrement de schéma d'URL n'est requis (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 distant ou de machine virtuelle par rapport aux machines Windows physiques. Testez l'intégralité du flux de connexion → WebView2 → rappel → token sur du matériel réel avant de publier.
Checklist de test :
- Flux de login : Cliquez sur login → le popup WebView2 s'ouvre → authentifiez-vous → le popup se ferme → les infos utilisateur s'affichent
- Flux de logout : Cliquez sur logout → le popup WebView2 s'ouvre → la session est effacée → le popup se ferme
- Rafraîchissement des tokens :
RefreshTokenAsyncavec un token de rafraîchissement stocké fonctionne - Annulation : L'utilisateur ferme le formulaire WebView2 → l'app gère
UserCancelgracieusement - Appareil physique : Testez sur une vraie machine Windows (pas juste un environnement virtuel)
- Connexions multiples : Vérifiez que la connexion fonctionne après la déconnexion (pas d'état obsolète)
Skills connexes
- auth0-wpf — Applications desktop WPF
- auth0-maui — Applications .NET MAUI multiplateformes
- auth0-aspnetcore-authentication — Applications web côté serveur ASP.NET Core
- 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"
});
// Login — ouvre le formulaire popup WebView2 (flux WebAuth avec 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();
// Rafraîchir le token (nécessite la portée offline_access)
var refreshToken = loginResult.RefreshToken;
var refreshResult = await client.RefreshTokenAsync(refreshToken);
if (refreshResult.IsError == false)
{
var newAccessToken = refreshResult.AccessToken;
}
Form1.cs (Exemple complet WinForms)
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();
}
}