Intégrer l’authentification Immersive

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.

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

    Afficher plus
    Réduire

    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.

    Login hébergé par RestFrontage : le nom de l'application accompagne la saisie des identifiants

    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.

    Vérification TOTP dans le login du serveur, avant le retour à l'application

    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

    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.

    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.

    Application WPF : configuration du serveur, connexion dans le navigateur et appel WebAPI
    1. Vérifiez l'adresse RestFrontage et l'identifiant de l'application.
    2. Choisissez Navigateur externe ou Navigateur intégré (WebView2), puis cliquez sur Se connecter.
    3. Terminez la saisie du mot de passe et, si elle est demandée, la vérification MFA.
    4. En mode externe, revenez dans le WPF. En mode intégré, la fenêtre de connexion se ferme automatiquement.
    5. 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é.

    Application WPF après la connexion intégrée : token reçu et appel WebAPI réussi

    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.

    Login Immersive affiché dans la fenêtre WebView2 de l'application WPF

    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.

    Vérification MFA dans la fenêtre intégrée avant récupération du token

    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.

    Application Web autonome avant la connexion
    1. Cliquez sur Se connecter : l'onglet est redirigé vers RestFrontage.
    2. Saisissez vos identifiants, puis le code MFA si nécessaire.
    3. Le serveur redirige l'onglet vers /auth/callback dans votre application.
    4. Le JavaScript vérifie le retour et échange le code contre le token.
    5. Cliquez sur Appeler en GET pour lire le contexte du compte.
    Retour dans l'application Web : token reçu et réponse authentifiée de l'API

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

    Exemple Web sur petit écran : connexion terminée et réponse authentifiée de l'API

    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.

    C#
    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();
    
    JavaScript
    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();
    
    HTTP
    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.

    HTTP
    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}}
    
    C#
    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();
    
    JavaScript
    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.