Intégrer l’authentification Immersive
- Type non défini
Documentation
Une application peut utiliser les écrans de connexion de RestFrontage pour authentifier ses utilisateurs, appliquer la MFA et récupérer un token utilisable avec les WebAPI et OData. Elle n'a pas à reproduire les écrans de mot de passe, de QR code ou de saisie TOTP.
Ce guide fournit deux projets complets : une application Windows WPF et une application Web en JavaScript, hébergée par un petit projet ASP.NET Core. Aucun des deux ne référence GraphicStream.Immersive.Server.Interop ni une autre DLL Immersive. Le futur package d'authentification indépendant n'est pas nécessaire pour les utiliser.
Télécharger les exemples
Télécharger les exemples d’intégration WPF et Web
Décompressez l’archive, puis ouvrez Samples/Immersive.Authentication.Samples.slnx dans Visual Studio.
Suivez ensuite la section Préparer les deux exemples pour déclarer les applications dans RestFrontage et configurer leur connexion.
Les illustrations sont des captures des exemples et du login RestFrontage dans un environnement de test isolé. Les comptes montrés sont des comptes de démonstration. Les ports et identifiants des captures proviennent du banc de test ; utilisez les valeurs de votre propre configuration.
Dans cet article
1. Comprendre le principe
1.1 Une interface de connexion commune
L'utilisateur clique sur Se connecter dans votre application. Le navigateur affiche le login Immersive. Il saisit son identifiant et son mot de passe, puis son code MFA lorsque la politique du serveur l'exige. Si sa vérification doit être configurée, le serveur lui présente le QR code et lui demande de confirmer un premier code.
L'application reçoit ensuite automatiquement un token. Ce token lui permet d'appeler les API avec les droits de l'utilisateur connecté. Une connexion réussie ne lui accorde aucun droit supplémentaire.
La MFA suit le paramétrage déjà défini dans Immersive : désactivée, obligatoire avec exemptions, ou obligatoire pour tous les utilisateurs concernés. L'application cliente ne choisit pas de contourner cette politique.

Le parcours pour une application est distinct de la connexion à l'administration RestFrontage. Un utilisateur ordinaire peut l'utiliser sans appartenir à EnhancedAccess. Ce parcours ne crée pas de session d'administration.
1.2 Deux codes qui ont des rôles différents
Le code TOTP est le code à six chiffres affiché par l'application du téléphone. Il sert à confirmer l'identité après le mot de passe. Il change généralement toutes les 30 secondes et se calcule sans Internet.
Le code de retour est un code technique, généré par le serveur après la connexion. Il est transmis automatiquement à l'application, qui l'échange contre le token. L'utilisateur n'a jamais à le recopier, à le conserver ou à le transmettre à un administrateur. Ce code expire après 60 secondes et ne fonctionne qu'une fois.

1.3 Le trajet complet
sequenceDiagram
participant A as Votre application
participant N as Navigateur
participant R as RestFrontage
A->>A: Préparer state et une preuve PKCE
A->>N: Ouvrir Browser/Authorize
N->>R: Demander la connexion pour l'application déclarée
R-->>N: Afficher le login Immersive
N->>R: Saisir identifiant et mot de passe
opt MFA requise
R-->>N: QR code si inscription nécessaire, puis saisie TOTP
N->>R: Confirmer un code à six chiffres
end
R-->>N: Rediriger vers le callback avec un code temporaire
N-->>A: Transmettre code, state et iss
A->>A: Vérifier le retour attendu
A->>R: Browser/Token avec le code et la preuve PKCE
R-->>A: Token Immersive et durée restante
A->>R: WebAPI ou OData avec Authorization: Bearer
R-->>A: Réponse autorisée selon les droits du compte
La protection PKCE S256 relie l'échange du code à l'application qui a démarré la connexion. L'application conserve une valeur aléatoire privée, le code_verifier, et ne transmet au départ que son empreinte, le code_challenge. Intercepter le code de retour seul ne suffit donc pas à obtenir le token. Ce mécanisme est décrit par la RFC 7636.
state relie le retour à la demande de connexion en cours. iss identifie le serveur qui répond. Les clients fournis vérifient ces valeurs et l'adresse de retour avant l'échange.
2. Préparer les deux exemples
2.1 Contenu du dossier fourni
Ouvrez Samples/Immersive.Authentication.Samples.slnx dans Visual Studio. La solution contient exactement deux projets indépendants.
| Projet | Fonction | Dépendances |
|---|---|---|
| Immersive.Authentication.Wpf | Exécutable Windows ; propose le navigateur externe ou une fenêtre WebView2 intégrée, puis appelle une API. | .NET 10 pour Windows, WPF et le package Microsoft.Web.WebView2. Aucune DLL Immersive. |
| Immersive.Authentication.Web | Application JavaScript ; redirige l'onglet vers Immersive puis échange le code au retour. | .NET 10 / ASP.NET Core pour servir les fichiers. Le JavaScript peut aussi être hébergé par un autre serveur Web. |
Le dossier Executables/Wpf, dans l'archive de livraison, contient l'exécutable publié et sa configuration. Cette version nécessite le .NET Desktop Runtime 10 x64 et, pour le mode intégré, le runtime Microsoft Edge WebView2. Conservez tous les fichiers publiés ensemble, y compris le chargeur WebView2.
Pour compiler les sources, utilisez le SDK .NET 10 et, dans Visual Studio, les composants de développement Desktop .NET et ASP.NET/Web. Les deux projets sont détachables du dépôt serveur : vous pouvez copier le dossier Samples sur un autre poste.
2.2 Déclarer les applications dans RestFrontage
Cette étape est obligatoire avant de cliquer sur Se connecter. Démarrer RestFrontage à la bonne adresse ne suffit pas : il doit connaître le ClientId de l'exemple et son callback. Une déclaration absente provoque le message « Demande de connexion invalide ». En développement, cette section peut être ajoutée à appsettings.Development.json de RestFrontage.
Ajoutez cette section à la configuration de l'instance RestFrontage, en remplaçant les adresses selon votre environnement. Le fichier appsettings.example.json contient le même exemple. Il ne remplace pas votre configuration existante.
{
"BrowserAuthentication": {
"Issuer": "https://localhost:44333",
"Clients": [
{
"ClientId": "immersive-desktop",
"DisplayName": "Exemple Immersive WPF",
"RedirectUris": [ "http://127.0.0.1/callback/" ],
"AllowLoopbackRedirect": true
},
{
"ClientId": "immersive-web",
"DisplayName": "Exemple Immersive Web",
"RedirectUris": [ "https://localhost:5173/auth/callback" ]
}
]
}
}
Issuer est l'origine HTTPS de RestFrontage telle que le navigateur y accède : schéma, hôte et éventuellement port, sans chemin ni barre finale. Ce parcours attend un serveur monté à la racine de cette origine. Si un reverse proxy est utilisé, le serveur doit recevoir le schéma et l'hôte externes corrects via sa configuration de confiance.
ClientId identifie l'application et n'est pas un secret. DisplayName est son nom affiché dans le login. Déclarez uniquement des applications autorisées à utiliser les droits de leurs utilisateurs. Aucun secret partagé ne doit être embarqué dans un binaire ou dans du JavaScript pour ces exemples.
RedirectUris liste les adresses de retour exactes. Aucun joker, paramètre de requête ou fragment n'est accepté. Chaque adresse Web utilise HTTPS. AllowLoopbackRedirect permet uniquement au client natif de choisir un port libre sur l'adresse de boucle locale déclarée ; l'hôte littéral et le chemin restent contrôlés. Avec l'exemple WPF, le retour devient par exemple http://127.0.0.1:54321/callback/.
Pour suspendre une application, ajoutez "Enabled": false à sa déclaration. Une entrée absente ou désactivée ne peut pas utiliser ce parcours.
localhost désigne le poste qui utilise le navigateur. Pour un vrai déploiement, remplacez l'adresse RestFrontage par son nom HTTPS accessible aux clients. L'adresse de retour 127.0.0.1 du WPF reste locale au poste de l'utilisateur, même si RestFrontage est hébergé ailleurs.
2.3 Vérifier HTTPS et les accès réseau
RestFrontage doit être joignable par le poste et disposer d'un certificat reconnu. Le projet Web utilise lui aussi HTTPS. Pour le test local ASP.NET Core, si nécessaire, installez le certificat de développement de confiance avec :
dotnet dev-certs https --trust
Les applications fournies ne désactivent pas la validation des certificats. Pour un réseau interne, utilisez un certificat reconnu par les postes concernés.
Pour le projet Web, RestFrontage doit autoriser les appels depuis l'origine de l'application, par exemple https://localhost:5173, dans sa politique CORS. La requête WebAPI doit notamment pouvoir envoyer l'en-tête Authorization. L'autorisation CORS ne remplace pas la déclaration du callback. Les appels du WPF ne dépendent pas de CORS.
La connexion fonctionne sans Internet si le poste atteint RestFrontage et l'application Web éventuelle sur le réseau interne. Les ressources des exemples sont locales. Le téléphone calcule son code TOTP hors ligne ; ses réglages de date et d'heure doivent rester corrects.
3. Utiliser l'exemple WPF
3.1 Lancer et se connecter
Dans le projet Immersive.Authentication.Wpf, le fichier appsettings.json définit les valeurs initiales :
{
"Server": "https://localhost:44333",
"ClientId": "immersive-desktop",
"BrowserMode": "External",
"ApiPath": "/api/Security/Mfa/Context"
}
Depuis le dossier Samples, lancez :
dotnet run --project Immersive.Authentication.Wpf
Vous pouvez aussi exécuter Immersive.Authentication.Wpf.exe depuis le dossier publié, ou définir ce projet comme projet de démarrage dans Visual Studio.

- Vérifiez l'adresse RestFrontage et l'identifiant de l'application.
- Choisissez Navigateur externe ou Navigateur intégré (WebView2), puis cliquez sur Se connecter.
- Terminez la saisie du mot de passe et, si elle est demandée, la vérification MFA.
- En mode externe, revenez dans le WPF. En mode intégré, la fenêtre de connexion se ferme automatiquement.
- Cliquez sur Appeler en GET. La route proposée retourne le nom du compte connecté.
Après une connexion réussie, le WPF affiche l'échéance du token. L'appel proposé renvoie HTTP 200 et le nom du compte connecté.

En mode externe, le retour utilise une écoute réseau temporaire, limitée à 127.0.0.1, sur un port choisi automatiquement. Cette écoute démarre avant l'ouverture du navigateur et s'arrête en fin de parcours. Le délai maximal de connexion est de dix minutes. Le bouton Annuler interrompt l'attente dans l'application ; il ne ferme pas l'onglet du navigateur.
3.2 Choisir le navigateur
Les deux choix utilisent le même serveur, le même ClientId et les mêmes vérifications de retour et PKCE. La MFA reste appliquée par Immersive. Il n'est pas nécessaire de déclarer une application supplémentaire pour passer de l'un à l'autre.
| Mode | Ce que voit l'utilisateur | Traitement du retour |
|---|---|---|
| Navigateur externe | Le navigateur système ouvre le login. L'utilisateur revient ensuite dans le WPF. C'est le choix par défaut. | Écoute temporaire sur 127.0.0.1, avec un port libre. |
| Navigateur intégré (WebView2) | Une fenêtre appartenant au WPF affiche le login. Elle se ferme automatiquement après connexion. | Le WPF intercepte la navigation vers http://127.0.0.1/callback/ avant son chargement, puis échange le code. Aucune écoute réseau locale n'est ouverte. |
Le réglage BrowserMode dans appsettings.json choisit la valeur initiale : External ou Embedded. La liste permet de changer de mode pour la prochaine connexion ; elle ne réécrit pas le fichier de configuration.

La fenêtre intégrée affiche l'origine du serveur au-dessus du login. Elle conserve les étapes habituelles, dont la saisie du code à six chiffres et l'inscription par QR code lorsque le serveur la demande. Annuler, la croix de fermeture ou l'expiration du délai interrompent la connexion et rendent la main au WPF.

Le profil WebView2 est privé et distinct de celui du navigateur habituel. L'enregistrement des mots de passe et le remplissage automatique sont désactivés. Les navigations hors du serveur configuré, les nouvelles fenêtres, les téléchargements et les accès aux objets natifs sont bloqués. Aucun script de lecture des identifiants n'est injecté par l'exemple. Les erreurs de certificat ne sont pas ignorées.
Le navigateur externe reste le choix par défaut pour isoler la page d'authentification de l'application. La variante intégrée convient à une application maîtrisée : son hébergeur peut techniquement accéder au contenu Web. PKCE protège l'échange du code, mais ne retire pas cette capacité au programme qui héberge WebView2. Les principes de protection du composant sont décrits dans la documentation Microsoft WebView2.
3.3 Préparer les postes pour WebView2
Le projet WPF référence Microsoft.Web.WebView2. Ce package fournit le contrôle et son chargeur ; le runtime Microsoft Edge WebView2 doit être présent sur le poste pour le mode intégré. Sa présence est distincte de celle du navigateur Edge. Si le runtime manque, l'exemple affiche un message et permet de choisir le navigateur externe.
Pour un poste sans Internet, prévoyez l'Evergreen Standalone Installer de l'architecture appropriée dans votre procédure de déploiement. Le petit bootstrapper Web nécessite un téléchargement et ne convient pas à une installation entièrement hors ligne. Le fonctionnement de la connexion reste possible sur le réseau interne une fois le runtime installé. Voir Distribuer WebView2.
Le dossier technique du composant est créé sous %LOCALAPPDATA%/Immersive.Authentication.Sample/WebView2, dans un emplacement accessible à l'utilisateur. Le profil de connexion est ouvert en mode privé. L'application conserve le token Immersive en mémoire dans les deux modes.
3.4 Réutiliser le code dans votre application
Le fichier BrowserAuthenticationClient.cs contient le client autonome. Il utilise les bibliothèques standard .NET pour préparer la demande, ouvrir le navigateur, contrôler le retour et échanger le code. Il n'a aucune dépendance au SDK Immersive.
using Immersive.Authentication.Wpf;
using var http = new HttpClient(new HttpClientHandler
{
AllowAutoRedirect = false,
UseCookies = false
});
var authentication = new BrowserAuthenticationClient(
"https://localhost:44333", http);
var session = await authentication.SignInAsync(
"immersive-desktop", cancellationToken);
// session.Token : token Immersive à garder en mémoire.
// session.ExpiresAt : échéance du token.
MainWindow.xaml.cs illustre le bouton de connexion, l'annulation, l'état de session et l'appel API. Vous pouvez changer le namespace du fichier autonome lorsque vous l'intégrez dans votre projet.
Pour le mode intégré, les fichiers EmbeddedLoginWindow.xaml et EmbeddedLoginWindow.xaml.cs complètent le client autonome. L'appel se fait depuis le thread UI WPF, avec la fenêtre principale comme propriétaire :
var session = await EmbeddedLoginWindow.SignInAsync(
this, authentication, "immersive-desktop", cancellationToken);
Le résultat possède les mêmes propriétés Token et ExpiresAt. Les contrôles du callback et l'échange HTTP restent dans BrowserAuthenticationClient.cs ; la fenêtre s'occupe uniquement de l'affichage et de l'interception de la navigation finale.
La méthode du navigateur externe peut recevoir une fonction openBrowser si votre application possède déjà son abstraction d'ouverture du navigateur. Les méthodes CreateBrowserLoginRequest et CompleteBrowserLoginAsync permettent de gérer séparément le démarrage et le retour si vous disposez déjà d'un mécanisme de callback compatible.
Le navigateur système garde la saisie des identifiants dans la page du serveur. Ce choix suit le principe recommandé pour les applications natives par la RFC 8252. Une iframe n'est pas un mode d'intégration de ce login.
4. Utiliser l'exemple Web
4.1 Lancer le site
Le fichier appsettings.json du projet Immersive.Authentication.Web contient :
{
"Authentication": {
"Server": "https://localhost:44333",
"ClientId": "immersive-web",
"ApiPath": "/api/Security/Mfa/Context"
}
}
Depuis Samples :
dotnet run --project Immersive.Authentication.Web
Ouvrez https://localhost:5173. Dans Visual Studio, le profil de lancement ouvre cette adresse automatiquement. La route de retour est https://localhost:5173/auth/callback ; elle doit être déclarée exactement ainsi dans RestFrontage.

- Cliquez sur Se connecter : l'onglet est redirigé vers RestFrontage.
- Saisissez vos identifiants, puis le code MFA si nécessaire.
- Le serveur redirige l'onglet vers
/auth/callbackdans votre application. - Le JavaScript vérifie le retour et échange le code contre le token.
- Cliquez sur Appeler en GET pour lire le contexte du compte.

Le même exemple Web adapte sa disposition aux petits écrans. Le parcours de connexion et l'utilisation du token restent identiques.

4.2 Réutiliser le module JavaScript
Les fichiers wwwroot/ImmersiveAuthentication.js et wwwroot/app.js montrent respectivement le client de connexion et son intégration dans la page. Le petit serveur ASP.NET Core sert ces ressources et la configuration publique. Il ne reçoit pas le token : le navigateur appelle directement RestFrontage.
import { ImmersiveAuthentication } from "/ImmersiveAuthentication.js";
const authentication = new ImmersiveAuthentication({
Server: "https://localhost:44333",
ClientId: "immersive-web",
RedirectUri: location.origin + "/auth/callback"
});
// Dans l'action « Se connecter » :
await authentication.SignIn();
Sur la page de retour, recréez le client avec les mêmes options, puis appelez :
const session = await authentication.CompleteSignIn();
// session.Token : token Immersive.
// session.ExpiresIn : durée restante, en secondes.
Le module conserve uniquement la transaction provisoire PKCE dans sessionStorage pendant le changement de page. Il supprime cette transaction après validation et retire le code de l'adresse du navigateur. Le token n'est écrit ni dans localStorage, ni dans sessionStorage, ni dans un cookie.
Le retour doit se produire dans le même onglet et sur la même origine que l'application qui a démarré la demande. La route /auth/callback doit être accessible directement sur votre hébergement, même avant le chargement du JavaScript. Dans l'exemple, le serveur renvoie index.html pour cette route.
Pour votre hébergement, conservez Referrer-Policy: no-referrer sur la page de retour, évitez les ressources tierces sur cette page et ne journalisez pas ses paramètres d'URL. Une configuration de proxy ou d'hébergement doit préserver ces propriétés.
5. Appeler les WebAPI et OData
5.1 Le même token quel que soit le client
Une fois la connexion terminée, les deux applications utilisent le même type de token Immersive. Elles ajoutent l'en-tête Authorization: Bearer à leurs requêtes. Voici la même opération en C#, JavaScript et HTTP ; server désigne l'origine RestFrontage et token le token obtenu.
using System.Net.Http.Headers;
using var request = new HttpRequestMessage(
HttpMethod.Get, server + "/api/Security/Mfa/Context");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
using var response = await http.SendAsync(request, cancellationToken);
string content = await response.Content.ReadAsStringAsync(cancellationToken);
response.EnsureSuccessStatusCode();
const response = await fetch(server + "/api/Security/Mfa/Context", {
headers: { Authorization: `Bearer ${token}`, Accept: "application/json" },
credentials: "omit",
cache: "no-store",
redirect: "error"
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const context = await response.json();
GET {{server}}/api/Security/Mfa/Context
Authorization: Bearer {{token}}
Accept: application/json
Une réponse réussie contient AccountName. Pour OData, remplacez le chemin par une route OData de votre instance : l'en-tête reste identique. Les exemples n'effectuent que des requêtes GET. Ils empêchent d'envoyer le token vers un autre serveur via le champ de chemin et refusent les redirections HTTP lors des appels authentifiés.
Un 401 signifie que la demande n'est pas authentifiée ou que le token n'est plus accepté ; recommencez la connexion. Un 403 indique un refus d'accès : vérifiez les droits et les règles de l'API concernée. Réussir la MFA ne donne pas accès à toutes les ressources.
5.2 Expiration et fin de session
Le token conserve sa durée de validité habituelle dans Immersive. La réponse d'échange indique sa durée restante. Les exemples cessent de l'utiliser à son expiration ; une nouvelle connexion est alors nécessaire. Ce parcours ne fournit pas de refresh token.
Effacer ma session supprime le token de la mémoire de l'exemple. Ce bouton ne révoque pas le token déjà émis sur le serveur et ne déconnecte pas toutes les autres applications. Fermer l'exécutable WPF ou recharger l'onglet Web efface aussi leur état de connexion.
Les projets montrent volontairement une session en mémoire. Une application qui veut conserver une session plus longtemps doit définir explicitement sa politique de stockage et de déconnexion. Pour un site avec backend, il est possible de garder le token exclusivement côté serveur.
6. Comprendre le contrat HTTP
6.1 Démarrer la connexion
L'application prépare des valeurs aléatoires state et code_verifier. Les clients fournis utilisent 32 octets aléatoires encodés en Base64URL, sans remplissage. Le challenge est BASE64URL(SHA256(ASCII(code_verifier))).
Elle ouvre ensuite cette adresse dans le navigateur, en encodant les valeurs des paramètres :
GET {{server}}/api/Security/Browser/Authorize?response_type=code&client_id={{clientId}}&redirect_uri={{redirectUriEncoded}}&state={{state}}&code_challenge={{challenge}}&code_challenge_method=S256
Ne démarrez pas l'intégration en ouvrant directement /Login : l'entrée Browser/Authorize porte les informations de l'application et du retour attendu. La demande de connexion est valable dix minutes.
Après succès, le serveur redirige vers le callback déclaré avec code, state et iss. Après annulation depuis le login, il renvoie error=access_denied, state et iss. Une demande initiale invalide reste sur une erreur locale : elle ne redirige pas vers une adresse non autorisée.
6.2 Échanger le code
Après avoir contrôlé le callback, state et iss, l'application transmet un formulaire HTTP. Les valeurs sont encodées comme un formulaire, sans conversion en JSON.
POST {{server}}/api/Security/Browser/Token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&client_id={{clientId}}&redirect_uri={{redirectUriEncoded}}&code={{code}}&code_verifier={{verifier}}
using var content = new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "authorization_code",
["client_id"] = clientId,
["redirect_uri"] = redirectUri,
["code"] = code,
["code_verifier"] = verifier
});
using var response = await http.PostAsync(server + "/api/Security/Browser/Token", content);
response.EnsureSuccessStatusCode();
const response = await fetch(server + "/api/Security/Browser/Token", {
method: "POST",
credentials: "omit",
cache: "no-store",
redirect: "error",
body: new URLSearchParams({
grant_type: "authorization_code",
client_id: clientId,
redirect_uri: redirectUri,
code,
code_verifier: verifier
})
});
if (!response.ok) throw new Error("Échange refusé : recommencez la connexion.");
La réponse contient :
{
"access_token": "JWT Immersive",
"token_type": "Bearer",
"expires_in": 3600
}
La durée est illustrative. Ces trois noms suivent le contrat OAuth, en minuscules. Le client WPF expose Token et ExpiresAt, et le module JavaScript expose Token et ExpiresIn. Les autres WebAPI Immersive conservent leur convention PascalCase.
Les routes Browser/VerifyCredentials, Browser/VerifyTotp et Browser/Cancel appartiennent au fonctionnement interne de l'interface hébergée. Votre intégration utilise Authorize et Token ; elle n'a pas à piloter les étapes du login.
7. Les autres moyens d'intégration
WPF et JavaScript ne sont pas les seuls choix. Le contrat est HTTP : les deux projets montrent deux manières de l'utiliser, pas une restriction de technologie.
| Intégration | Où se trouve le token ? | Compatibilité actuelle |
|---|---|---|
| WPF, WinForms, outil de bureau ou console interactive | En mémoire dans le processus. | Parcours navigateur externe avec callback sur boucle locale. Le WPF fournit aussi une fenêtre WebView2 ; son adaptation à un autre framework nécessite son contrôle de navigateur. |
| React, Vue, Angular, JavaScript ou autre application exécutée dans le navigateur | En mémoire dans l'onglet. | Le module JavaScript peut être intégré au framework choisi. Déclarer une vraie route de callback HTTPS et configurer CORS. |
| Site avec backend : ASP.NET, PHP, Java, Node.js… | En session côté backend. | Le backend peut préparer PKCE, recevoir le callback HTTPS et échanger le code. Le navigateur ne reçoit qu'un cookie de session propre au site. Ce guide décrit le principe ; il ne fournit pas un troisième projet. |
| Application mobile | Dans le processus ou le stockage protégé de la plateforme selon sa conception. | Le principe navigateur reste applicable. Les liens HTTPS associés à l'application nécessitent une intégration de plateforme. Les schémas privés comme monapp:// ne sont pas acceptés par le serveur actuel. Aucun exemple mobile n'est fourni ici. |
| Interface de connexion entièrement personnalisée | Dans l'application qui appelle directement les API MFA. | Les API MFA existantes permettent ce parcours, mais l'application doit gérer les identifiants, l'inscription, les codes et les erreurs. L'interface hébergée évite cette duplication. |
| Service, automatisation ou tâche planifiée sans utilisateur | Secret d'application conservé dans sa configuration protégée. | Utiliser une clé API. Une connexion interactive MFA n'est pas adaptée à une exécution sans personne. |
7.1 Variante Web avec backend
Dans cette variante, le backend conserve state et la preuve PKCE dans la session utilisateur avant la redirection. Il contrôle le callback puis échange le code côté serveur. Il conserve ensuite le token Immersive et effectue les appels API pour le navigateur.
sequenceDiagram
participant N as Navigateur
participant B as Backend de votre site
participant R as RestFrontage
N->>B: Se connecter
B->>B: Stocker state et PKCE dans la session
B-->>N: Redirection vers le login hébergé
N->>R: Mot de passe et MFA éventuelle
R-->>N: Redirection vers le callback du site
N->>B: Callback avec code et state
B->>B: Vérifier session, state et iss
B->>R: Échanger code et PKCE
R-->>B: Token Immersive
B-->>N: Session du site, cookie sécurisé HttpOnly
N->>B: Demander une ressource
B->>R: Appeler l'API avec le token
R-->>B: Résultat autorisé
B-->>N: Résultat pour l'interface
Le cookie de session doit notamment être sécurisé, HttpOnly et adapté au retour de navigation. Protégez les actions du site contre les requêtes intersites. Le token reste sur le backend ; il ne doit pas être renvoyé au navigateur par une route utilitaire. Les contrôles PKCE et state restent nécessaires dans cette variante.
8. Périmètre et diagnostic
8.1 Ce que ce parcours couvre
Le parcours hébergé couvre identifiant/mot de passe et TOTP, avec les exemptions, la première inscription et le réenregistrement autorisé prévus dans Immersive. Il ne raccorde pas encore les fournisseurs SSO existants à cette entrée ; leur fonctionnement propre demeure distinct.
Le serveur utilise le mécanisme Authorization Code avec PKCE, mais n'est pas présenté comme un fournisseur OpenID Connect complet. Ce lot ne fournit pas de discovery OIDC, d'ID token, de consentement par scopes, de refresh token ou de Device Authorization Flow. Un composant qui exige ces fonctions ne peut pas être branché sans adaptation.
Pour plusieurs instances RestFrontage, l'exploitant doit conserver un trousseau Data Protection persistant partagé, la même identité d'application Data Protection et la même base Security. Les clés JWT et le paramétrage MFA doivent également être cohérents. Une perte des protections temporaires impose de recommencer les connexions en cours.
8.2 Résoudre les erreurs habituelles
| Symptôme | Vérification |
|---|---|
| Demande de connexion invalide dès l'ouverture | Vérifier Issuer, le ClientId activé, la correspondance exacte du callback et S256. |
| Le navigateur refuse HTTPS | Vérifier le certificat RestFrontage et celui du site Web, leur nom et la confiance du poste. |
| Le login réussit mais le retour Web échoue | Vérifier la route /auth/callback, le même onglet, sessionStorage, les origines CORS et le nom public du serveur. |
| Le navigateur intégré ne démarre pas | Vérifier le runtime WebView2 et les droits sur son dossier de données. Choisir le navigateur externe si nécessaire. |
| Le navigateur intégré refuse le serveur | Vérifier son certificat HTTPS et l'origine configurée. Les navigations vers un autre domaine sont bloquées. |
| La fenêtre WPF attend après le login | Vérifier le retour sur 127.0.0.1 et le port temporaire, les règles locales du poste, puis recommencer si l'attente a été annulée. |
| invalid_grant lors de l'échange | Le code peut être expiré, déjà utilisé, lié à une autre preuve ou invalidé par une modification du compte ou de la politique. Recommencer depuis Se connecter. |
| L'API retourne 401 ou 403 | Vérifier la validité du token et les droits du compte pour l'opération concernée. |
| La connexion disparaît après un rechargement Web | C'est le comportement de cet exemple : le token reste uniquement en mémoire. |
Ne journalisez pas les tokens, les preuves PKCE, les mots de passe, les secrets TOTP ou les paramètres des callbacks. Cette consigne concerne aussi IIS, le reverse proxy et les journaux des applications clientes. Les bonnes pratiques générales sont détaillées dans la RFC 9700.
8.3 Vérifier votre intégration
Testez un compte soumis à la MFA, un compte qui doit la configurer pour la première fois et, si votre politique les autorise, un compte exempté. Vérifiez aussi une annulation, une erreur de code TOTP et un accès API refusé par manque de droits.
Le résultat attendu est toujours le même : votre application récupère un token seulement après les étapes de connexion exigées par le serveur. Elle peut ensuite utiliser les API dans la limite des droits du compte.