Guide du développeur de l'API Federated Credential Management

Découvrez comment utiliser FedCM pour la fédération d'identité protégeant la confidentialité.

FedCM (Federated Credential Management) est une approche protégeant la confidentialité des services d'identité fédérée (tels que "Se connecter avec...") qui permet aux utilisateurs de se connecter à des sites sans partager leurs informations personnelles avec le service d'identité ou le site.

Pour en savoir plus sur les cas d'utilisation de FedCM, les parcours utilisateur et la feuille de route des API, consultez la présentation de l'API FedCM.

Environnement de développement FedCM

Pour utiliser FedCM, vous avez besoin d'un contexte sécurisé (HTTPS ou localhost) à la fois sur l'IDP et la RP dans Chrome.

Déboguer du code dans Chrome sur Android

Configurez et exécutez un serveur localement pour déboguer votre code FedCM. Vous pouvez accéder à ce serveur dans Chrome sur un appareil Android connecté à l'aide d'un câble USB avec transfert de port.

Pour déboguer Chrome sur Android à l'aide de DevTools sur un ordinateur, suivez les instructions de la section Déboguer à distance des appareils Android.

Bloquer les cookies tiers sur Chrome

Simuler l'abandon progressif des cookies tiers en configurant Chrome pour les bloquer
Simuler l'abandon progressif des cookies tiers en configurant Chrome pour les bloquer

Vous pouvez tester le fonctionnement de FedCM sans cookies tiers sur Chrome avant son application effective.

Pour bloquer les cookies tiers, utilisez le mode navigation privée ou choisissez "Bloquer les cookies tiers" dans les paramètres de votre ordinateur sur chrome://settings/cookies ou sur mobile en accédant à Paramètres > Paramètres du site > Cookies.

Utiliser l'API FedCM

Pour intégrer FedCM, créez un fichier connu, un fichier de configuration et des points de terminaison pour la liste des comptes, l'émission d'assertions et éventuellement des métadonnées client.

À partir de là, FedCM expose des API JavaScript que les RP peuvent utiliser pour se connecter avec l'IDP.

Créer un fichier well-known

Pour empêcher les outils de suivi d'utiliser l'API de manière abusive, un fichier connu doit être diffusé à partir de l'adresse /.well-known/web-identity de l'eTLD+1 du fournisseur d'identité.

Par exemple, si les points de terminaison du fournisseur d'identité sont diffusés sous https://accounts.idp.example/, ils doivent diffuser un fichier connu dans https://idp.example/.well-known/web-identity, ainsi qu'un fichier de configuration d'IdP. Voici un exemple de contenu de fichier connu :

{
  "provider_urls": ["https://accounts.idp.example/config.json"]
}

Le fichier JSON doit contenir la propriété provider_urls avec un tableau d'URL de fichiers de configuration IdP pouvant être spécifiées en tant que partie du chemin d'accès de configURL dans navigator.credentials.get par les RP. Le nombre de chaînes d'URL dans le tableau est limité à une, mais cela pourrait changer en fonction de vos commentaires.

Créer un fichier de configuration de l'IDP et des points de terminaison

Le fichier de configuration de l'IdP fournit la liste des points de terminaison requis pour le navigateur. Les fournisseurs d'identité hébergent ce fichier de configuration, ainsi que les points de terminaison et les URL requis. Toutes les réponses JSON doivent être diffusées avec le type de contenu application/json.

L'URL du fichier de configuration est déterminée par les valeurs fournies à l'appel navigator.credentials.get exécuté sur un RP.

const credential = await navigator.credentials.get({
  identity: {
    context: 'signup',
    providers: [{
      configURL: 'https://accounts.idp.example/config.json',
      clientId: '********',
      nonce: '******'
    }]
  }
});
const { token } = credential;

Indiquez l'URL complète de l'emplacement du fichier de configuration de l'IdP en tant que configURL. Lorsque navigator.credentials.get() est appelé sur le RP, le navigateur extrait le fichier de configuration avec une requête GET sans l'en-tête Origin ni l'en-tête Referer. La requête ne contient pas de cookies et ne suit pas les redirections. Cela empêche efficacement l'IDP de savoir qui a effectué la requête et quel RP tente de se connecter. Exemple :

GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity

Le navigateur attend une réponse JSON de l'IDP qui inclut les propriétés suivantes :

Propriété Description
accounts_endpoint (obligatoire) URL du point de terminaison des comptes.
client_metadata_endpoint (facultatif) URL du point de terminaison des métadonnées client.
id_assertion_endpoint (obligatoire) URL du point de terminaison d'assertion d'ID.
disconnect (facultatif) URL du point de terminaison de déconnexion.
login_url (obligatoire) URL de la page de connexion permettant à l'utilisateur de se connecter au fournisseur d'identité.
branding (facultatif) Objet contenant différentes options de branding.
branding.background_color (facultatif) Option de branding qui définit la couleur d'arrière-plan du bouton "Continuer en tant que…". Utilisez la syntaxe CSS appropriée, à savoir hex-color, hsl(), rgb() ou named-color.
branding.color (facultatif) Option de branding qui définit la couleur du texte du bouton "Continuer en tant que…". Utilisez la syntaxe CSS appropriée, à savoir hex-color, hsl(), rgb() ou named-color.
branding.icons (facultatif) Option de marque qui définit l'objet icône, affiché dans la boîte de dialogue de connexion. L'objet icône est un tableau avec deux paramètres :
  • url (obligatoire): URL de l'image de l'icône. Cette option n'est pas compatible avec les images SVG.
  • size (facultatif) : dimensions de l'icône, supposées être carrées et de résolution unique par l'application. Ce nombre doit être supérieur ou égal à 25.

Le RP peut modifier la chaîne dans l'UI de la boîte de dialogue FedCM via la valeur identity.context pour navigator.credentials.get() afin de prendre en charge les contextes d'authentification prédéfinis. La propriété facultative peut être "signin" (par défaut), "signup", "use" ou "continue".

Comment le branding est-il appliqué à la boîte de dialogue FedCM ?
Comment le branding est-il appliqué à la boîte de dialogue FedCM ?

Voici un exemple de corps de réponse de l'IDP :

{
  "accounts_endpoint": "/accounts.php",
  "client_metadata_endpoint": "/client_metadata.php",
  "id_assertion_endpoint": "/assertion.php",
  "disconnect_endpoint": "/disconnect.php",
  "login_url": "/login",
  "branding": {
    "background_color": "green",
    "color": "#FFEEAA",
    "icons": [{
      "url": "https://idp.example/icon.ico",
      "size": 25
    }]
  }
}

Une fois que le navigateur a récupéré le fichier de configuration, il envoie les requêtes suivantes aux points de terminaison de l'IDP :

Points de terminaison de l'IDP
Points de terminaison du fournisseur d'identité

Point de terminaison "Accounts" (Comptes)

Le point de terminaison des comptes du fournisseur d'identité renvoie la liste des comptes auxquels l'utilisateur est actuellement connecté sur le fournisseur d'identité. Si l'IDP prend en charge plusieurs comptes, ce point de terminaison renvoie tous les comptes connectés.

Le navigateur envoie une requête GET avec des cookies avec SameSite=None, mais sans paramètre client_id, en-tête Origin ou en-tête Referer. Cela empêche efficacement l'IdP d'apprendre à quel RP l'utilisateur tente de se connecter. Exemple :

GET /accounts.php HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Cookie: 0x23223
Sec-Fetch-Dest: webidentity

À la réception de la requête, le serveur doit:

  1. Vérifiez que la requête contient un en-tête HTTP Sec-Fetch-Dest: webidentity.
  2. Faites correspondre les cookies de session avec les ID des comptes déjà connectés.
  3. Répondez avec la liste des comptes.

Le navigateur attend une réponse JSON qui inclut une propriété accounts avec un tableau d'informations de compte avec les propriétés suivantes :

Propriété Description
id (obligatoire) Identifiant unique de l'utilisateur.
name (obligatoire) Prénom et nom de famille de l'utilisateur.
email (obligatoire) Adresse e-mail de l'utilisateur.
given_name (facultatif) Prénom de l'utilisateur.
picture (facultatif) URL de l'avatar de l'utilisateur.
approved_clients (facultatif) Tableau des ID client des tiers assujettis à des restrictions auprès desquels l'utilisateur s'est enregistré.
login_hints (facultatif) Tableau de tous les types de filtres possibles compatibles avec l'IDP pour spécifier un compte. Le RP peut appeler navigator.credentials.get() avec la propriété loginHint pour afficher de manière sélective le compte spécifié.
domain_hints (facultatif) Tableau de tous les domaines auxquels le compte est associé. Le tiers assujetti à des restrictions peut appeler navigator.credentials.get() avec une propriété domainHint pour filtrer les comptes.

Exemple de corps de réponse :

{
  "accounts": [{
    "id": "1234",
    "given_name": "John",
    "name": "John Doe",
    "email": "john_doe@idp.example",
    "picture": "https://idp.example/profile/123",
    "approved_clients": ["123", "456", "789"],
    "login_hints": ["demo1", "demo1@idp.example"]
  }, {
    "id": "5678",
    "given_name": "Johnny",
    "name": "Johnny",
    "email": "johnny@idp.example",
    "picture": "https://idp.example/profile/456",
    "approved_clients": ["abc", "def", "ghi"],
    "login_hints": ["demo2", "demo2@idp.example"],
    "domain_hints": ["corp.example"]
  }]
}

Si l'utilisateur n'est pas connecté, répondez avec le code HTTP 401 (Non autorisé).

La liste des comptes renvoyée est utilisée par le navigateur et ne sera pas disponible pour le tiers assujetti à des restrictions.

Point de terminaison des métadonnées client

Le point de terminaison des métadonnées client de l'IDP renvoie les métadonnées de la partie de confiance, telles que ses règles de confidentialité et ses conditions d'utilisation. Les RP doivent fournir au préalable des liens vers leurs règles de confidentialité et leurs conditions d'utilisation au fournisseur d'identité. Ces liens s'affichent dans la boîte de dialogue de connexion lorsque l'utilisateur ne s'est pas encore inscrit auprès du RP auprès du fournisseur d'identité.

Le navigateur envoie une requête GET à l'aide de client_id navigator.credentials.get sans cookies. Exemple :

GET /client_metadata.php?client_id=1234 HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Accept: application/json
Sec-Fetch-Dest: webidentity

Une fois la requête reçue, le serveur doit :

  1. Déterminez le RP pour client_id.
  2. Répondez avec les métadonnées du client.

Les propriétés du point de terminaison des métadonnées client incluent :

Propriété Description
privacy_policy_url (facultatif) URL des règles de confidentialité du tiers assujetti à des restrictions.
terms_of_service_url (facultatif) URL des conditions d'utilisation de la RP.

Le navigateur s'attend à recevoir une réponse JSON du point de terminaison :

{
  "privacy_policy_url": "https://rp.example/privacy_policy.html",
  "terms_of_service_url": "https://rp.example/terms_of_service.html",
}

Les métadonnées client renvoyées sont consommées par le navigateur et ne sont pas disponibles pour le RP.

Point de terminaison d'assertion d'identité

Le point de terminaison d'assertion d'ID du fournisseur d'identité renvoie une assertion pour l'utilisateur connecté. Lorsque l'utilisateur se connecte à un site Web RP à l'aide de l'appel navigator.credentials.get(), le navigateur envoie une requête POST avec des cookies avec SameSite=None et un type de contenu application/x-www-form-urlencoded à ce point de terminaison avec les informations suivantes :

Propriété Description
client_id (obligatoire) Identifiant client du tiers assujetti à des restrictions.
account_id (obligatoire) Identifiant unique de l'utilisateur qui se connecte.
nonce (facultatif) Nonce de requête, fourni par le RP.
disclosure_text_shown Il en résulte une chaîne de "true" ou "false" (plutôt qu'une valeur booléenne). Le résultat est "false" si le texte d'information n'a pas été affiché. Cela se produit lorsque l'ID client du RP a été inclus dans la liste de propriétés approved_clients de la réponse du point de terminaison accounts ou si le navigateur a observé un moment d'inscription par le passé en l'absence de approved_clients.
is_auto_selected Si la réauthentification automatique est effectuée sur le tiers assujetti à des restrictions, is_auto_selected indique "true". Sinon, il est défini sur "false". Cela permet de prendre en charge davantage de fonctionnalités liées à la sécurité. Par exemple, certains utilisateurs peuvent préférer un niveau de sécurité plus élevé qui nécessite une médiation explicite de l'utilisateur lors de l'authentification. Si un IdP reçoit une requête de jeton sans cette médiation, il peut traiter la requête différemment. Par exemple, renvoyez un code d'erreur permettant à la partie assujettie à des restrictions de pouvoir appeler à nouveau l'API FedCM avec mediation: required.

Exemple d'en-tête HTTP :

POST /assertion.php HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity

account_id=123&client_id=client1234&nonce=Ct60bD&disclosure_text_shown=true&is_auto_selected=true

À la réception de la requête, le serveur doit:

  1. Répondez à la requête avec le partage de ressources entre origines (CORS).
  2. Vérifiez que la requête contient un en-tête HTTP Sec-Fetch-Dest: webidentity.
  3. Faites correspondre l'en-tête Origin avec l'origine de la RP déterminée par le client_id. Si ce n'est pas le cas, refusez-les.
  4. Faites correspondre account_id à l'ID du compte déjà connecté. Refusez-les si elles ne correspondent pas.
  5. Répondez avec un jeton. Si la requête est rejetée, renvoyez une réponse d'erreur.

La manière dont le jeton est émis dépend du fournisseur d'identité, mais en général, il est signé avec des informations telles que l'ID de compte, l'ID client, l'origine de l'émetteur, nonce, afin que la RP puisse vérifier que le jeton est authentique.

Le navigateur attend une réponse JSON qui inclut la propriété suivante :

Propriété Description
token (obligatoire) Un jeton est une chaîne qui contient des revendications concernant l'authentification.
{
  "token": "***********"
}

Le jeton renvoyé est transmis à la RP par le navigateur, afin que celle-ci puisse valider l'authentification.

Renvoyez une réponse d'erreur.

id_assertion_endpoint peut également renvoyer une réponse "error", qui comporte deux champs facultatifs :

  • code : l'IdP peut choisir l'une des erreurs connues de la liste d'erreurs spécifiée par OAuth 2.0 (invalid_request, unauthorized_client, access_denied, server_error et temporarily_unavailable) ou utiliser une chaîne arbitraire. Dans ce cas, Chrome affiche l'UI d'erreur avec un message d'erreur générique et transmet le code au RP.
  • url: identifie une page Web lisible par l'humain et contient des informations sur l'erreur afin de fournir aux utilisateurs des renseignements supplémentaires sur celle-ci. Ce champ est utile pour les utilisateurs, car les navigateurs ne peuvent pas fournir de messages d'erreur enrichis dans une interface utilisateur native. (par exemple, des liens vers les étapes suivantes, les coordonnées du service client, etc.). Si un utilisateur souhaite en savoir plus sur les détails de l'erreur et sur la façon de la corriger, il peut consulter la page fournie à partir de l'interface utilisateur du navigateur pour en savoir plus. L'URL doit correspondre au même site que l'IdP configURL.
// id_assertion_endpoint response
{
  "error" : {
     "code": "access_denied",
     "url" : "https://idp.example/error?type=access_denied"
  }
}

Déconnecter un point de terminaison

En appelant IdentityCredential.disconnect(), le navigateur envoie une requête POST multi-origine avec des cookies avec SameSite=None et un type de contenu application/x-www-form-urlencoded à ce point de terminaison de déconnexion avec les informations suivantes:

Propriété Description
account_hint Indice pour le compte IdP.
client_id Identifiant client du tiers assujetti à des restrictions.
POST /disconnect.php HTTP/1.1
Host: idp.example
Origin: rp.example
Content-Type: application/x-www-form-urlencoded
Cookie: 0x123
Sec-Fetch-Dest: webidentity

account_hint=account456&client_id=rp123

À la réception de la requête, le serveur doit:

  1. Répondre à la requête avec CORS (Cross-Origin Resource Sharing).
  2. Vérifiez que la requête contient un en-tête HTTP Sec-Fetch-Dest: webidentity.
  3. Faites correspondre l'en-tête Origin avec l'origine de la RP déterminée par le client_id. Si ce n'est pas le cas, refusez-les.
  4. Faites correspondre account_hint avec les ID des comptes déjà connectés.
  5. Déconnectez le compte utilisateur du RP.
  6. Répondez au navigateur avec les informations du compte utilisateur identifié au format JSON.

Voici un exemple de charge utile JSON de réponse:

{
  "account_id": "account456"
}

Au lieu de cela, si le fournisseur d'identité souhaite que le navigateur dissocie tous les comptes associés à l'RP, transmettez une chaîne qui ne correspond à aucun ID de compte, par exemple "*".

URL de connexion

Avec l'API Login Status, le fournisseur d'identité doit informer le navigateur de l'état de connexion de l'utilisateur. Toutefois, l'état peut être désynchronisé, par exemple lorsque la session expire. Dans un tel scénario, le navigateur peut permettre à l'utilisateur de se connecter de manière dynamique au fournisseur d'identité via l'URL de la page de connexion spécifiée dans le login_url du fichier de configuration idp.

La boîte de dialogue FedCM affiche un message suggérant une connexion, comme illustré dans l'image suivante.

A
Boîte de dialogue FedCM suggérant de se connecter au fournisseur d'identité.

Lorsque l'utilisateur clique sur le bouton Continue (Continuer), le navigateur ouvre une fenêtre pop-up pour la page de connexion du fournisseur d'identité.

Exemple de boîte de dialogue FedCM
Exemple de boîte de dialogue affichée après avoir cliqué sur le bouton de connexion à l'IDP.

La boîte de dialogue est une fenêtre de navigateur standard contenant des cookies propriétaires. Tout ce qui se passe dans la boîte de dialogue dépend de l'IDP, et aucune poignée de fenêtre n'est disponible pour effectuer une requête de communication inter-origine à la page RP. Une fois l'utilisateur connecté, le fournisseur d'identité doit:

  • Envoyez l'en-tête Set-Login: logged-in ou appelez l'API navigator.login.setStatus("logged-in") pour informer le navigateur que l'utilisateur s'est connecté.
  • Appelez IdentityProvider.close() pour fermer la boîte de dialogue.
Un utilisateur se connecte à un tiers assujetti à des restrictions après s'être connecté au fournisseur d'identité à l'aide de FedCM.

Informer le navigateur de l'état de connexion de l'utilisateur auprès du fournisseur d'identité

L'API Login Status est un mécanisme par lequel un site Web, en particulier un fournisseur d'identité, informe le navigateur de l'état de connexion de l'utilisateur sur le fournisseur d'identité. Avec cette API, le navigateur peut réduire les requêtes inutiles à l'IDP et atténuer les attaques par cassage de chiffrement.

Les fournisseurs d'identité peuvent signaler l'état de connexion de l'utilisateur au navigateur en envoyant un en-tête HTTP ou en appelant une API JavaScript lorsque l'utilisateur est connecté sur le fournisseur d'identité ou lorsqu'il est déconnecté de tous ses comptes IdP. Pour chaque fournisseur d'identité (identifié par son URL de configuration), le navigateur conserve une variable à trois états représentant l'état de connexion avec les valeurs possibles logged-in, logged-out et unknown. L'état par défaut est unknown.

Pour indiquer que l'utilisateur est connecté, envoyez un en-tête HTTP Set-Login: logged-in dans une navigation de premier niveau ou une requête de sous-ressource du même site à l'origine de l'IDP :

Set-Login: logged-in

Vous pouvez également appeler l'API JavaScript navigator.login.setStatus("logged-in") à partir de l'origine de l'IdP dans une navigation de premier niveau:

navigator.login.setStatus("logged-in")

Ces appels enregistrent l'état de connexion de l'utilisateur sous la forme logged-in. Lorsque l'état de connexion de l'utilisateur est défini sur logged-in, le RP appelant FedCM envoie des requêtes au point de terminaison des comptes de l'IDP et affiche les comptes disponibles à l'utilisateur dans la boîte de dialogue FedCM.

Pour signaler que l'utilisateur est déconnecté de tous ses comptes, envoyez l'en-tête HTTP Set-Login: logged-out dans une navigation de niveau supérieur ou une requête de sous-ressource du même site à l'origine de l'IDP :

Set-Login: logged-out

Vous pouvez également appeler l'API JavaScript navigator.login.setStatus("logged-out") à partir de l'origine de l'IdP dans une navigation de premier niveau:

navigator.login.setStatus("logged-out")

Ces appels enregistrent l'état de connexion de l'utilisateur comme logged-out. Lorsque l'état de connexion de l'utilisateur est logged-out, l'appel de FedCM échoue de manière silencieuse sans envoyer de requête au point de terminaison des comptes de l'IDP.

L'état unknown est défini avant que l'IdP n'envoie un signal à l'aide de l'API Login Status. Unknown a été introduit pour une meilleure transition, car un utilisateur peut s'être déjà connecté au fournisseur d'identité lors de l'expédition de cette API. Le fournisseur d'identité n'a peut-être pas la possibilité de signaler cela au navigateur au moment où FedCM est appelé pour la première fois. Dans ce cas, Chrome envoie une requête au point de terminaison des comptes du fournisseur d'identité et met à jour l'état en fonction de la réponse du point de terminaison des comptes:

  • Si le point de terminaison renvoie une liste de comptes actifs, définissez l'état sur logged-in et ouvrez la boîte de dialogue FedCM pour afficher ces comptes.
  • Si le point de terminaison ne renvoie aucun compte, mettez à jour l'état sur logged-out et échouez à l'appel FedCM.

Autoriser l'utilisateur à se connecter via un flux de connexion dynamique

Même si le fournisseur d'identité continue d'informer le navigateur de l'état de connexion de l'utilisateur, il peut être désynchronisé, par exemple à l'expiration de la session. Le navigateur tente d'envoyer une requête avec identifiants au point de terminaison des comptes lorsque l'état de connexion est logged-in, mais le serveur ne renvoie aucun compte, car la session n'est plus disponible. Dans un tel scénario, le navigateur peut permettre à l'utilisateur de se connecter de manière dynamique au fournisseur d'identité via une fenêtre pop-up.

Se connecter au tiers de confiance avec le fournisseur d'identité

Une fois la configuration et les points de terminaison de l'IDP disponibles, les RP peuvent appeler navigator.credentials.get() pour demander aux utilisateurs de se connecter à la RP avec l'IDP.

Avant d'appeler l'API, vous devez vérifier que [FedCM est disponible dans le navigateur de l'utilisateur]. Pour vérifier si FedCM est disponible, encapsulez ce code autour de votre implémentation FedCM:

if ('IdentityCredential' in window) {
  // If the feature is available, take action
}

Pour demander à autoriser les utilisateurs à se connecter à l'IDP à partir du RP, procédez comme suit, par exemple :

const credential = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://accounts.idp.example/config.json',
      clientId: '********',
      nonce: '******'
    }]
  }
});
const { token } = credential;

La propriété providers utilise un tableau d'objets IdentityProvider ayant les propriétés suivantes:

Propriété Description
configURL (obligatoire) Chemin d'accès complet au fichier de configuration de l'IdP.
clientId (obligatoire) Identifiant client de la RP, émis par le fournisseur d'identité.
nonce (facultatif) Chaîne aléatoire garantissant l'émission de la réponse pour cette demande spécifique. Empêche les attaques par rejeu.
loginHint (facultatif) En spécifiant l'une des valeurs login_hints fournies par les points de terminaison des comptes, la boîte de dialogue FedCM affiche de manière sélective le compte spécifié.
domainHint (facultatif) En spécifiant l'une des valeurs domain_hints fournies par les points de terminaison des comptes, la boîte de dialogue FedCM affiche de manière sélective le compte spécifié.

Le navigateur gère les cas d'utilisation de l'inscription et de la connexion différemment en fonction de l'existence de approved_clients dans la réponse du point de terminaison de la liste des comptes. Le navigateur n'affiche pas le texte d'information "Pour continuer avec ...." si l'utilisateur s'est déjà inscrit au RP.

L'état d'inscription est déterminé en fonction de la réalisation ou non des conditions suivantes :

  • Si approved_clients inclut le clientId du RP.
  • Si le navigateur se souvient que l'utilisateur s'est déjà inscrit auprès du RP.
Un utilisateur se connecte à un tiers assujetti à des restrictions à l'aide de FedCM.

Lorsque la RP appelle navigator.credentials.get(), les activités suivantes ont lieu:

  1. Le navigateur envoie des requêtes et récupère plusieurs documents :
    1. Le fichier well-known et un fichier de configuration de l'IDP qui déclarent les points de terminaison.
    2. Liste des comptes
    3. Facultatif : URL des règles de confidentialité et des conditions d'utilisation de la RP, récupérées à partir du point de terminaison des métadonnées client.
  2. Le navigateur affiche la liste des comptes que l'utilisateur peut utiliser pour se connecter, ainsi que les conditions d'utilisation et les règles de confidentialité, le cas échéant.
  3. Une fois que l'utilisateur a choisi un compte avec lequel se connecter, une requête adressée au point de terminaison d'assertion d'ID est envoyée au fournisseur d'identité pour récupérer un jeton.
  4. La RP peut valider le jeton pour authentifier l'utilisateur.
Appel d'API de connexion
appel d'API de connexion

Les tiers assujettis à des restrictions sont censés être compatibles avec les navigateurs non compatibles avec FedCM. Les utilisateurs doivent donc pouvoir utiliser un processus de connexion existant non FedCM. Tant que les cookies tiers ne seront pas complètement abandonnés, cela ne devrait pas poser de problème.

Une fois le jeton validé par le serveur de la RP, celle-ci peut enregistrer l'utilisateur ou l'autoriser à se connecter et à démarrer une nouvelle session.

API Login Hint

Une fois l'utilisateur connecté, le tiers de confiance (RP) lui demande parfois de se réauthentifier. Toutefois, l'utilisateur ne sait peut-être pas avec certitude quel compte il a utilisé. Si le RP peut spécifier le compte avec lequel se connecter, l'utilisateur pourra choisir plus facilement un compte.

Les tiers assujettis à des restrictions peuvent afficher un compte spécifique de manière sélective en appelant navigator.credentials.get() avec la propriété loginHint avec l'une des valeurs login_hints récupérées à partir du point de terminaison de la liste des comptes, comme illustré dans l'exemple de code suivant:

return await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.example/manifest.json",
      clientId: "123",
      nonce: nonce,
      loginHint : "demo1@example.com"
    }]
  }
});

Si aucun compte ne correspond à l'identifiant loginHint, la boîte de dialogue FedCM affiche une invite de connexion qui permet à l'utilisateur de se connecter à un compte IdP correspondant à l'indice demandé par le tiers assujetti à des restrictions. Lorsque l'utilisateur appuie sur l'invite, une fenêtre pop-up s'ouvre avec l'URL de connexion spécifiée dans le fichier de configuration. Le lien est ensuite ajouté avec l'indice de connexion et les paramètres de requête d'indice de domaine.

API Domain Hint

Dans certains cas, le tiers assujetti à des restrictions sait déjà que seuls les comptes associés à un domaine donné sont autorisés à se connecter au site. Cela est particulièrement courant dans les scénarios d'entreprise où l'accès au site est limité à un domaine d'entreprise. Pour offrir une meilleure expérience utilisateur, l'API FedCM permet au RP de n'afficher que les comptes pouvant être utilisés pour se connecter au RP. Cela permet d'éviter les scénarios dans lesquels un utilisateur tente de se connecter au tiers assujetti à des restrictions à l'aide d'un compte extérieur au domaine de l'entreprise, pour ensuite recevoir un message d'erreur (ou être mis sous silence lorsque la connexion n'a pas fonctionné), car le type de compte approprié n'a pas été utilisé.

Les RP ne peuvent afficher de manière sélective que les comptes correspondants en appelant navigator.credentials.get() avec la propriété domainHint avec l'une des valeurs domain_hints extraites du point de terminaison de la liste des comptes, comme illustré dans l'exemple de code suivant :

return await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.example/manifest.json",
      clientId: "abc",
      nonce: nonce,
      domainHint : "corp.example"
    }]
  }
});

Lorsqu'aucun compte ne correspond à domainHint, la boîte de dialogue FedCM affiche une invite de connexion, qui permet à l'utilisateur de se connecter à un compte d'IDP correspondant à l'indice demandé par le RP. Lorsque l'utilisateur appuie sur l'invite, une fenêtre pop-up s'ouvre avec l'URL de connexion spécifiée dans le fichier de configuration. Le lien est ensuite ajouté avec l'indice de connexion et les paramètres de requête d'indice de domaine.

Exemple d'invite de connexion lorsqu'aucun compte ne correspond à domainHint.
Exemple de requête de connexion lorsqu'aucun compte ne correspond à domainHint.

Afficher un message d'erreur

Il arrive que l'IDP ne puisse pas émettre de jeton pour des raisons légitimes, par exemple lorsque le client n'est pas autorisé ou que le serveur est temporairement indisponible. Si l'IDP renvoie une réponse "erreur", le RP peut la détecter, et Chrome avertit l'utilisateur en affichant une UI de navigateur avec les informations d'erreur fournies par l'IDP.

A
Fenêtre de dialogue FedCM affichant le message d'erreur après l'échec de la tentative de connexion de l'utilisateur. La chaîne est associée au type d'erreur.
try {
  const cred = await navigator.credentials.get({
    identity: {
      providers: [
        {
          configURL: "https://idp.example/manifest.json",
          clientId: "1234",
        },
      ],
    }
  });
} catch (e) {
  const code = e.code;
  const url = e.url;
}

Réauthentifier automatiquement les utilisateurs après l'authentification initiale

La réauthentification automatique FedCM (en abrégé "auto-reauthn") permet aux utilisateurs de se réauthentifier automatiquement lorsqu'ils reviennent après leur authentification initiale à l'aide de FedCM. "L'authentification initiale" signifie ici que l'utilisateur crée un compte ou se connecte au site Web du tiers assujetti à des restrictions en appuyant sur le bouton Continuer en tant que dans la boîte de dialogue de connexion de FedCM pour la première fois dans la même instance de navigateur.

Bien que l'expérience utilisateur explicite soit logique avant que l'utilisateur ait créé le compte fédéré pour empêcher le suivi (ce qui constitue l'un des principaux objectifs de FedCM), elle devient inutilement fastidieuse lorsque l'utilisateur l'a effectuée une fois. Une fois que l'utilisateur a autorisé la communication entre le tiers assujetti à des restrictions et le fournisseur d'identité, l'application d'une autre confirmation explicite de l'utilisateur n'offre aucun avantage en termes de confidentialité ou de sécurité.

Avec la réauthentification automatique, le navigateur modifie son comportement en fonction de l'option que vous spécifiez pour mediation lors de l'appel de navigator.credentials.get().

const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.example/fedcm.json",
      clientId: "1234",
    }],
  },
  mediation: 'optional', // this is the default
});

// `isAutoSelected` is `true` if auto-reauthn was performed.
const isAutoSelected = cred.isAutoSelected;

mediation est une propriété de l'API de gestion des identifiants. Elle se comporte de la même manière que pour PasswordCredential et FederatedCredential. Elle est également partiellement prise en charge par PublicKeyCredential. La propriété accepte les quatre valeurs suivantes :

  • 'optional' (par défaut) : réautorisation automatique si possible, nécessite une médiation si ce n'est pas le cas. Nous vous recommandons de choisir cette option sur la page de connexion.
  • 'required': une médiation est toujours nécessaire pour pouvoir continuer, par exemple en cliquant sur le bouton "Continuer" de l'interface utilisateur. Sélectionnez cette option si vos utilisateurs doivent accorder une autorisation explicite chaque fois qu'ils doivent être authentifiés.
  • 'silent': effectuez une réauthentification automatique si possible. Dans le cas contraire, échouez silencieusement sans nécessiter de médiation. Nous vous recommandons de choisir cette option sur les pages autres que la page de connexion dédiée, mais sur lesquelles vous souhaitez que les utilisateurs restent connectés (par exemple, une page d'article sur un site d'actualités ou une page d'article sur un site d'actualités).
  • 'conditional': utilisé pour WebAuthn et non disponible pour FedCM pour le moment.

Avec cet appel, la réautorisation automatique se produit si les conditions suivantes sont remplies :

  • FedCM est disponible. Par exemple, l'utilisateur n'a pas désactivé FedCM de manière globale ni pour le tiers assujetti à des restrictions dans les paramètres.
  • L'utilisateur n'a utilisé qu'un seul compte avec l'API FedCM pour se connecter au site Web dans ce navigateur.
  • L'utilisateur est connecté au fournisseur d'identité avec ce compte.
  • La réautorisation automatique n'a pas eu lieu au cours des 10 dernières minutes.
  • Le RP n'a pas appelé navigator.credentials.preventSilentAccess() après la connexion précédente.

Lorsque ces conditions sont remplies, une tentative de réauthentification automatique de l'utilisateur commence dès que le navigator.credentials.get() FedCM est appelé.

Lorsque mediation: optional, la réauthentification automatique peut être indisponible pour des raisons que seul le navigateur connaît. Le RP peut vérifier si la réauthentification automatique est effectuée en examinant la propriété isAutoSelected.

Cela permet d'évaluer les performances de l'API et d'améliorer l'expérience utilisateur en conséquence. De plus, lorsque cette option n'est pas disponible, l'utilisateur peut être invité à se connecter via la médiation utilisateur explicite, qui est un parcours avec mediation: required.

Un utilisateur qui s'authentifie automatiquement via FedCM

Appliquer la médiation avec preventSilentAccess()

La réauthentification automatique des utilisateurs immédiatement après leur déconnexion ne serait pas une bonne expérience utilisateur. C'est pourquoi FedCM dispose d'une période silencieuse de 10 minutes après une réauthentification automatique pour éviter ce comportement. Cela signifie que la réauthentification automatique se produit au maximum toutes les 10 minutes, sauf si l'utilisateur se reconnecte dans les 10 minutes. Le RP doit appeler navigator.credentials.preventSilentAccess() pour demander explicitement au navigateur de désactiver la réauthentification automatique lorsqu'un utilisateur se déconnecte explicitement du RP, par exemple en cliquant sur un bouton de déconnexion.

function signout() {
  navigator.credentials.preventSilentAccess();
  location.href = '/signout';
}

Les utilisateurs peuvent désactiver la réauthentification automatique dans les paramètres

Les utilisateurs peuvent désactiver la réautorisation automatique dans le menu des paramètres :

  • Sur un ordinateur, dans Chrome, accédez à chrome://password-manager/settings > Se connecter automatiquement.
  • Dans Chrome pour Android, accédez à Paramètres > Gestionnaire de mots de passe > Appuyez sur une roue dentée en haut à droite > Connexion automatique.

En désactivant le bouton d'activation/de désactivation, l'utilisateur peut désactiver complètement le comportement de réauthentification automatique. Ce paramètre est stocké et synchronisé sur tous les appareils, si l'utilisateur est connecté à un compte Google sur l'instance Chrome et que la synchronisation est activée.

Déconnecter l'IdP du tiers assujetti à des restrictions

Si un utilisateur s'est déjà connecté au RP à l'aide de l'IdP via FedCM, la relation est mémorisée localement par le navigateur sous la forme de la liste des comptes connectés. La RP peut déclencher une déconnexion en appelant la fonction IdentityCredential.disconnect(). Cette fonction peut être appelée à partir d'une trame RP de premier niveau. La RP doit transmettre un configURL, le clientId qu'il utilise sous le fournisseur d'identité et un accountHint pour que celui-ci soit déconnecté. Un indice de compte peut être une chaîne arbitraire tant que le point de terminaison de déconnexion peut identifier le compte, par exemple une adresse e-mail ou un ID utilisateur qui ne correspond pas nécessairement à l'ID de compte fourni par le point de terminaison de la liste de comptes:

// Disconnect an IdP account "account456" from the RP "https://idp.com/". This is invoked on the RP domain.
IdentityCredential.disconnect({
  configURL: "https://idp.com/config.json",
  clientId: "rp123",
  accountHint: "account456"
});

IdentityCredential.disconnect() renvoie un Promise. Cette promesse peut générer une exception pour les raisons suivantes :

  • L'utilisateur ne s'est pas connecté au tiers assujetti à des restrictions à l'aide du fournisseur d'identité via FedCM.
  • L'API est appelée à partir d'un iFrame sans stratégie d'autorisation FedCM.
  • La configURL n'est pas valide ou ne contient pas de point de terminaison de déconnexion.
  • Échec de la vérification de la CSP (Content Security Policy).
  • Une demande de dissociation est en attente.
  • L'utilisateur a désactivé FedCM dans les paramètres du navigateur.

Lorsque le point de terminaison de déconnexion du fournisseur d'identité renvoie une réponse, la RP et le fournisseur d'identité sont déconnectés dans le navigateur, et la promesse est résolue. L'ID des comptes déconnectés est spécifié dans la réponse du point de terminaison de déconnexion.

Appeler FedCM à partir d'un iFrame d'origine différente

FedCM peut être appelé à partir d'un iFrame multi-origine à l'aide d'une règle d'autorisation identity-credentials-get, si le frame parent le permet. Pour ce faire, ajoutez l'attribut allow="identity-credentials-get" au tag iFrame comme suit:

<iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>

Vous pouvez voir un exemple de ce comportement.

Si le frame parent souhaite restreindre les origines pour appeler FedCM, envoyez un en-tête Permissions-Policy avec une liste des origines autorisées.

Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")

Pour en savoir plus sur le fonctionnement du règlement sur les autorisations, consultez Contrôler les fonctionnalités du navigateur avec le règlement sur les autorisations.