Implémenter une solution d'identité avec FedCM

La gestion des identifiants fédérés (FedCM, Federated Credential Management) est une approche respectueuse de la confidentialité des services d'identité fédérés (comme "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.

L'implémentation de la FedCM comprend plusieurs étapes essentielles pour le fournisseur d'identité (IdP) et la partie de confiance (RP).

Pour implémenter FedCM, les IdPs doivent suivre les étapes suivantes:

Pour activer FedCM sur leur site, les RP doivent suivre les étapes suivantes:

Implémenter FedCM en tant que fournisseur d'identité

Découvrez comment implémenter FedCM du côté de l'IDP.

Créer un fichier well-known

Pour empêcher les traceurs d'abuser de l'API, un fichier well-known doit être diffusé à partir de /.well-known/web-identity de l'eTLD+1 de l'IdP.

Le fichier connu peut inclure les propriétés suivantes:

Propriété Requis Description
provider_urls required Tableau de chemins d'accès aux fichiers de configuration de l'IDP. Ignoré (mais toujours obligatoire) si accounts_endpoint et login_url sont spécifiés.
accounts_endpoint recommandé, nécessite login_url
URL du point de terminaison des comptes. Cela permet de prendre en charge plusieurs configurations, à condition que chaque fichier de configuration utilise la même URL login_url et accounts_endpoint.

Remarque: Le paramètre est compatible à partir de Chrome 132.
login_url recommandé, nécessite accounts_endpoint URL de la page de connexion permettant à l'utilisateur de se connecter à l'IDP. Cela permet de prendre en charge plusieurs configurations, à condition que chaque fichier de configuration utilise les mêmes login_url et accounts_endpoint.

Remarque: Le paramètre est compatible à partir de Chrome 132 ou version ultérieure.

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

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

Les IdP peuvent accepter plusieurs fichiers de configuration pour un IdP en spécifiant accounts_endpoint et login_url dans le fichier well-known.
Cette fonctionnalité peut être utile dans les cas suivants:

  • Un IdP doit prendre en charge plusieurs configurations de test et de production différentes.
  • Un IdP doit prendre en charge différentes configurations par région (par exemple, eu-idp.example et us-idp.example).

Pour prendre en charge plusieurs configurations (par exemple, pour différencier l'environnement de test de l'environnement de production), l'IDP doit spécifier accounts_endpoint et login_url:

  {
    // This property is required, but will be ignored when IdP supports
    // multiple configs (when `accounts_endpoint` and `login_url` are
    // specified), as long as `accounts_endpoint` and `login_url` in
    // that config file match those in the well-known file.
    "provider_urls": [ "https://idp.example/fedcm.json" ],

    // Specify accounts_endpoint and login_url properties to support
    // multiple config files.
    // Note: The accounts_endpoint and login_url must be identical
    // across all config files. Otherwise,
    // the configurations won't be supported.
    "accounts_endpoint": "https://idp.example/accounts",
    "login_url": "https://idp.example/login"
  }

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

Le fichier de configuration de l'IDP fournit une liste des points de terminaison requis pour le navigateur. Les IdP doivent héberger un ou plusieurs fichiers 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;

Le RP transmet l'URL du fichier de configuration à l'appel de l'API FedCM pour permettre à l'utilisateur de se connecter:

  // Executed on RP's side:
  const credential = await navigator.credentials.get({
    identity: {
      context: 'signup',
      providers: [{
        // To allow users to sign in with an IdP using FedCM, RP specifies the IdP's config file URL:
        configURL: 'https://accounts.idp.example/fedcm.json',
        clientId: '********',
  });
  const { token } = credential;

Le navigateur récupère 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

L'IDP doit implémenter un point de terminaison de configuration qui répond avec un JSON. Le fichier JSON inclut les propriétés suivantes:

Propriété Description
accounts_endpoint (obligatoire) URL du point de terminaison des comptes.
accounts.include (facultatif) Chaîne de libellé de compte personnalisée, qui détermine les comptes à renvoyer lorsque ce fichier de configuration est utilisé (par exemple, "accounts": {"include": "developer"}).
Un IdP peut implémenter le libellé de compte personnalisé comme suit:

Par exemple, un IdP implémente le fichier de configuration "https://idp.example/developer-config.json" avec "accounts": {"include": "developer"} spécifié. Le fournisseur d'identité marque également certains comptes avec l'étiquette "developer" à l'aide du paramètre labels dans le point de terminaison des comptes. Lorsqu'un RP appelle navigator.credentials.get() avec le fichier de configuration "https://idp.example/developer-config.json" spécifié, seuls les comptes associés au libellé "developer" sont renvoyés.
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 à l'IDP.
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) Tableau d'objets d'icônes. Ces icônes s'affichent dans la boîte de dialogue de connexion. L'objet icône comporte deux paramètres :
  • url (obligatoire): URL de l'image de l'icône. Les images SVG ne sont pas compatibles.
  • size (facultatif): dimensions de l'icône, supposées être carrées et à résolution unique par l'application. Ce nombre doit être supérieur ou égal à 25 px en mode passif et supérieur ou égal à 40 px en mode actif.
modes Objet contenant des spécifications sur l'affichage de l'UI FedCM dans différents modes:
  • active
  • passive
modes.active Objet contenant des propriétés permettant de personnaliser le comportement de FedCM dans un mode spécifique. modes.active et modes.passive peuvent tous deux contenir le paramètre suivant:
  • supports_use_other_account: valeur booléenne indiquant si l'utilisateur peut se connecter avec un compte différent de celui avec lequel il est actuellement connecté (si l'IDP prend en charge plusieurs comptes).

Remarque: La fonctionnalité Utiliser un autre compte et le mode actif sont compatibles à partir de Chrome 132.
modes.passive

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

  {
    "accounts_endpoint": "/accounts.example",
    "client_metadata_endpoint": "/client_metadata.example",
    "id_assertion_endpoint": "/assertion.example",
    "disconnect_endpoint": "/disconnect.example",
    "login_url": "/login",
    // When RPs use this config file, only those accounts will be
    //returned that include `developer` label in the accounts endpoint.
    "accounts": {"include": "developer"},
    "modes": {
        "active": {
          "supports_use_other_account": true,
        }
    },
    "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 de l'IDP

Utiliser un autre compte

Les utilisateurs peuvent passer à un compte différent de celui avec lequel ils sont actuellement connectés si l'IDP accepte plusieurs comptes ou remplace le compte existant.

Pour permettre à l'utilisateur de choisir d'autres comptes, l'IDP doit spécifier cette fonctionnalité dans le fichier de configuration:

  {
    "accounts_endpoint" : "/accounts.example",
    "modes": {
      "active": {
        // Allow the user to choose other account (false by default)
        "supports_use_other_account": true
      }
      // "passive" mode can be configured separately
    }
  }

Point de terminaison des comptes

Le point de terminaison des comptes de l'IdP renvoie la liste des comptes auxquels l'utilisateur est connecté sur l'IdP. 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.example HTTP/1.1
  Host: accounts.idp.example
  Accept: application/json
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

Une fois la requête reçue, 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 aux 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'image de l'avatar de l'utilisateur.
approved_clients (facultatif) Tableau d'ID client RP avec lesquels 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 RP peut appeler navigator.credentials.get() avec une propriété domainHint pour filtrer les comptes.
labels (facultatif) Tableau de chaînes de libellés de compte personnalisés auxquels un compte est associé.
Un IdP peut implémenter le libellé de compte personnalisé comme suit:
  • Spécifiez des libellés de compte dans le point de terminaison des comptes (à l'aide de ce paramètre labels).
  • Créez un fichier de configuration pour chaque libellé spécifique.

Par exemple, un IdP implémente le fichier de configuration https://idp.example/developer-config.json avec "accounts": {"include": "developer"} spécifié. Le fournisseur d'identité marque également certains comptes avec l'étiquette "developer" à l'aide du paramètre labels dans le point de terminaison des comptes. Lorsqu'un RP appelle navigator.credentials.get() avec le fichier de configuration https://idp.example/developer-config.json spécifié, seuls les comptes associés au libellé "developer" sont renvoyés.

Les libellés de compte personnalisés sont différents de l'indice de connexion et de l'indice de domaine, car ils sont entièrement gérés par le serveur du fournisseur d'identité, et le RP ne spécifie que le fichier de configuration à utiliser.

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",
      // Ids of those RPs where this account can be used
      "approved_clients": ["123", "456", "789"],
      // This account has 'login_hints`. When an RP calls `navigator.credentials.get()`
      // with a `loginHint` value specified, for example, `exampleHint`, only those
      // accounts will be shown to the user whose 'login_hints' array contains the `exampleHint`.
      "login_hints": ["demo1", "exampleHint"],
      // This account is labelled. IdP can implement a specific config file for a
      // label, for example, `https://idp.example/developer-config.json`. Like that
      // RPs can filter out accounts by calling `navigator.credentials.get()` with
      // `https://idp.example/developer-config.json` config file.
      "labels": ["hr", "developer"]
    }, {
      "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"],
      "domain_hints": ["@domain.example"]
    }]
  }

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

La liste des comptes renvoyée est utilisée par le navigateur et n'est pas disponible pour le RP.

Point de terminaison d'assertion d'identité

Le point de terminaison d'assertion d'identité de l'IdP renvoie une assertion pour son 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 de l'RP.
account_id (obligatoire) Identifiant unique de l'utilisateur qui se connecte.
disclosure_text_shown Résultats sous forme de chaîne "true" ou "false" (plutôt que sous forme de valeur booléenne). Le résultat est "false" dans les cas suivants:
  • Si le texte d'information n'a pas été affiché, car l'ID client du RP était inclus dans la liste de propriétés approved_clients de la réponse du point de terminaison accounts.
  • Si le texte d'information n'a pas été affiché, car le navigateur a observé un moment d'inscription dans le passé en l'absence de approved_clients.
  • Si le paramètre fields n'inclut pas un ou plusieurs des trois champs ("name", "email" et "picture"), par exemple, fields=[ ] ou fields=['name', 'picture']. Cela est nécessaire pour la rétrocompatibilité avec les anciennes implémentations d'IDP qui s'attendent à ce qu'une chaîne de divulgation inclue toujours les trois champs.
is_auto_selected Si la réauthentification automatique est effectuée sur le RP, 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 afin que le RP puisse à nouveau appeler l'API FedCM avec mediation: required.
fields (facultatif) Tableau de chaînes qui spécifie les informations utilisateur ("name", "email", "picture") que l'RP doit demander à l'IdP de partager avec lui.
Le navigateur envoie fields, disclosure_text_shown et disclosure_shown_for en listant les champs spécifiés dans la requête POST, comme dans l'exemple suivant.

Remarque: Le paramètre "Fields" est compatible avec Chrome 132 et versions ultérieures.
params (facultatif) Tout objet JSON valide permettant de spécifier des paramètres clé-valeur personnalisés supplémentaires, par exemple :
  • scope: valeur de chaîne contenant des autorisations supplémentaires que le RP doit demander, par exemple "drive.readonly calendar.readonly"
  • nonce: chaîne aléatoire fournie par le RP pour s'assurer que la réponse est émise pour cette requête spécifique. Empêche les attaques par rejeu.
  • Autres paramètres de clé-valeur personnalisés.
Lorsque le navigateur envoie une requête POST, la valeur params est sérialisée au format JSON, puis encodée en pourcentage.

Remarque: L'API Parameters est compatible avec Chrome 132 et versions ultérieures.

Exemple d'en-tête HTTP:

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

  // disclosure_text_shown is set to 'false', as the 'name' field value is missing in 'fields' array
  // params value is serialized to JSON and then percent-encoded.
  account_id=123&client_id=client1234&disclosure_text_shown=false&is_auto_selected=true&params=%22%7B%5C%22nonce%5C%22%3A%5C%22nonce-value%5C%22%7D%22.%0D%0A4&disclosure_text_shown=true&fields=email,picture&disclosure_shown_for=email,picture

Une fois la requête reçue, 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 à l'origine du RP déterminée par client_id. Refusez-les si elles ne correspondent pas.
  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, répondez par une réponse d'erreur.

L'IDP peut décider de la manière dont il émet le jeton. En général, il est signé avec des informations telles que l'ID de compte, l'ID client, l'origine de l'émetteur et le nonce, afin que le 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 Un jeton est une chaîne qui contient des revendications concernant l'authentification.
continue_on URL de redirection permettant d'activer une procédure de connexion en plusieurs étapes.

Le jeton renvoyé est transmis au RP par le navigateur afin que le RP puisse valider l'authentification.

  {
    // IdP can respond with a token to authenticate the user
    "token": "***********"
  }
Continuer sur la fonctionnalité

L'IdP peut fournir une URL de redirection dans la réponse du point de terminaison d'assertion d'identité pour activer un flux de connexion en plusieurs étapes. Cela est utile lorsque l'IDP doit demander des informations ou des autorisations supplémentaires, par exemple:

  • Autorisation d'accéder aux ressources côté serveur de l'utilisateur.
  • Vérification que les coordonnées sont à jour
  • Contrôle parental.

Le point de terminaison d'assertion d'identité peut renvoyer une propriété continue_on qui inclut un chemin absolu ou relatif vers le point de terminaison d'assertion d'identité.

  {
    // In the id_assertion_endpoint, instead of returning a typical
    // "token" response, the IdP decides that it needs the user to
    // continue on a popup window:
    "continue_on": "https://idp.example/continue_on_url"
  }

Si la réponse contient le paramètre continue_on, une nouvelle fenêtre pop-up s'ouvre et redirige l'utilisateur vers le chemin d'accès spécifié. Une fois que l'utilisateur a interagi avec la page continue_on, l'IDP doit appeler IdentityProvider.resolve() avec le jeton transmis en tant qu'argument afin que la promesse de l'appel navigator.credentials.get() d'origine puisse être résolue:

  document.getElementById('example-button').addEventListener('click', async () => {
    let accessToken = await fetch('/generate_access_token.cgi');
    // Closes the window and resolves the promise (that is still hanging
    // in the relying party's renderer) with the value that is passed.
    IdentityProvider.resolve(accessToken);
  });

Le navigateur ferme alors automatiquement la fenêtre pop-up et renvoie le jeton à l'appelant de l'API. Un appel IdentityProvider.resolve() unique est le seul moyen pour la fenêtre parente (RP) et la fenêtre pop-up (IdP) de communiquer.
Si l'utilisateur refuse la requête, l'IDP peut fermer la fenêtre en appelant IdentityProvider.close().

  IdentityProvider.close();

Pour fonctionner, l'API Continuation nécessite une interaction explicite de l'utilisateur (clics). Voici comment l'API Continuation fonctionne avec différents modes de médiation:

  • En mode passif :
    • mediation: 'optional' (par défaut): l'API Continuation ne fonctionne qu'avec un geste de l'utilisateur, tel que cliquer sur un bouton sur la page ou dans l'interface utilisateur de FedCM. Lorsque la réauthentification automatique est déclenchée sans geste de l'utilisateur, aucune fenêtre pop-up ne s'ouvre et la promesse est rejetée.
    • mediation: 'required': demande toujours à l'utilisateur d'interagir, de sorte que l'API Continuation fonctionne toujours.
  • En mode actif :
    • L'activation de l'utilisateur est toujours requise. L'API Continuation est compatible.

Si, pour une raison quelconque, l'utilisateur a modifié son compte dans le pop-up (par exemple, si l'IDP propose une fonction "Utiliser un autre compte" ou en cas de délégation), l'appel de résolution accepte un deuxième argument facultatif permettant, par exemple, de:

  IdentityProvider.resolve(token, {accountId: '1234');
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'utilisateur avec des informations sur l'erreur pour fournir des informations supplémentaires aux utilisateurs. Ce champ est utile aux utilisateurs, car les navigateurs ne peuvent pas fournir de messages d'erreur riches dans une UI intégrée. (par exemple, des liens vers les prochaines étapes ou les coordonnées du service client). 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 dans l'UI du navigateur. L'URL doit être du même site que l'configURL de l'IDP.
  // id_assertion_endpoint response
  {
    "error" : {
      "code": "access_denied",
      "url" : "https://idp.example/error?type=access_denied"
    }
  }

Libellés de compte personnalisés

Avec les libellés de compte personnalisés, l'IDP peut annoter les comptes utilisateur avec des libellés, et le RP peut choisir de n'extraire que les comptes avec des libellés spécifiques en spécifiant le configURL pour ce libellé spécifique. Cela peut être utile lorsqu'un RP doit filtrer les comptes en fonction de critères spécifiques, par exemple pour n'afficher que les comptes spécifiques au rôle, tels que "developer" ou "hr".

Un filtrage similaire est possible à l'aide des fonctionnalités Invite de domaine et Invite de connexion, en les spécifiant dans l'appel navigator.credentials.get(). Toutefois, les libellés de compte personnalisés peuvent filtrer les utilisateurs en spécifiant le fichier de configuration, ce qui est particulièrement utile lorsque plusieurs configURLs sont utilisés. Les libellés de compte personnalisés sont également différents en ce sens qu'ils sont fournis par le serveur de l'IDP, et non par le RP, comme les indications de connexion ou de domaine.

Prenons l'exemple d'un IdP qui souhaite différencier les comptes "developer" et "hr". Pour ce faire, l'IDP doit prendre en charge deux configURL pour "developer" et "hr", respectivement:

  • Le fichier de configuration du développeur https://idp.example/developer/fedcm.json comporte un libellé "developer", et le fichier de configuration de l'entreprise https://idp.example/hr/fedcm.json comporte un libellé "hr" comme suit:
  // The developer config file at `https://idp.example/developer/fedcm.json`
  {
    "accounts_endpoint": "https://idp.example/accounts",
    "client_metadata_endpoint": "/client_metadata",
    "login_url": "https://idp.example/login",
    "id_assertion_endpoint": "/assertion",
    "accounts": {
      // Account label
      "include": "developer"
    }
  }
  // The hr config file at `https://idp.example/hr/fedcm.json`
  {
    "accounts_endpoint": "https://idp.example/accounts",
    "client_metadata_endpoint": "/client_metadata",
    "login_url": "https://idp.example/login",
    "id_assertion_endpoint": "/assertion",
    "accounts": {
      // Account label
      "include": "hr"
    }
  }
  • Avec une telle configuration, le fichier well-known doit inclure accounts_endpoint et login_url pour autoriser plusieurs configURLs:
  {
    "provider_urls": [ "https://idp.example/fedcm.json" ],
    "accounts_endpoint": "https://idp.example/accounts",
    "login_url": "https://idp.example/login"
  }
  • Le point de terminaison des comptes de l'IDP commun (https://idp.example/accounts dans cet exemple) renvoie une liste de comptes incluant une propriété labels avec des libellés attribués dans un tableau pour chaque compte:
  {
  "accounts": [{
    "id": "123",
    "given_name": "John",
    "name": "John Doe",
    "email": "john_doe@idp.example",
    "picture": "https://idp.example/profile/123",
    "labels": ["developer"]
    }], [{
    "id": "4567",
    "given_name": "Jane",
    "name": "Jane Doe",
    "email": "jane_doe@idp.example",
    "picture": "https://idp.example/profile/4567",
    "labels": ["hr"]
    }]
  }

Lorsqu'un RP souhaite autoriser les utilisateurs "hr" à se connecter, il peut spécifier la valeur https://idp.example/hr/fedcm.json configURL dans l'appel navigator.credentials.get():

  let { token } = await navigator.credentials.get({
    identity: {
      providers: [{
        clientId: '1234',
        nonce: '234234',
        configURL: 'https://idp.example/hr/fedcm.json',
      },
    }
  });

Par conséquent, seul l'ID de compte 4567 est disponible pour que l'utilisateur puisse se connecter. L'ID de compte 123 est masqué de manière silencieuse par le navigateur afin que l'utilisateur ne reçoive pas de compte non compatible avec l'IDP sur ce site.

  • Les libellés sont des chaînes. Si le tableau labels ou le champ include contient un élément autre qu'une chaîne, il est ignoré.
  • Si aucun libellé n'est spécifié dans configURL, tous les comptes s'affichent dans le sélecteur de comptes FedCM.
  • Si aucun libellé n'est spécifié pour un compte, il ne s'affiche dans le sélecteur de comptes que si configURL ne spécifie pas non plus de libellé.
  • Si aucun compte ne correspond au libellé demandé en mode passif (comme pour la fonctionnalité d'indice de domaine), la boîte de dialogue FedCM affiche une invite de connexion, qui permet à l'utilisateur de se connecter à un compte d'IDP. Pour le mode actif, la fenêtre pop-up de connexion s'ouvre directement.

Déconnecter un point de terminaison

En appelant IdentityCredential.disconnect(), le navigateur envoie une requête POST inter-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 de l'RP.
  POST /disconnect.example 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

Une fois la requête reçue, 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 à l'origine du RP déterminée par client_id. Refusez-les si elles ne correspondent pas.
  4. Faites correspondre account_hint aux 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 "*".

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é, ses conditions d'utilisation et ses icônes de logo. 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.example?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é de la RP.
terms_of_service_url (facultatif) URL des conditions d'utilisation de la RP.
icons (facultatif) Tableau d'objets, tels que [{ "url": "https://rp.example/rp-icon.ico", "size": 40}]

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",
    "icons": [{
          "url": "https://rp.example/rp-icon.ico",
          "size": 40
      }]
  }

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

URL de connexion

Ce point de terminaison permet à l'utilisateur de se connecter à l'IDP.

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 ce cas, le navigateur peut autoriser l'utilisateur à se connecter dynamiquement à l'IDP via l'URL de la page de connexion spécifiée avec le login_url du fichier de configuration de l'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 Continuer (Continuer), le navigateur ouvre une fenêtre pop-up pour la page de connexion de l'IDP.

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 RP après s'être connecté au fournisseur d'identité à l'aide de FedCM.

Informer le navigateur de l'état de connexion de l'utilisateur

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é. Grâce à cette API, le navigateur peut réduire les requêtes inutiles envoyées à l'IDP et atténuer les attaques par cassage de chiffrement potentielles.

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é au fournisseur d'identité ou lorsqu'il est déconnecté de tous ses comptes de fournisseur d'identité. Pour chaque IdP (identifié par son URL de configuration), le navigateur conserve une variable à trois états représentant l'état de connexion avec les valeurs possibles suivantes:

  • logged-in
  • logged-out
  • unknown (par défaut)
État de connexion Description
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.
logged-out Lorsque l'état de connexion de l'utilisateur est logged-out, l'appel du FedCM échoue de manière silencieuse sans envoyer de requête au point de terminaison des comptes de l'IDP.
unknown (par défaut) L'état unknown est défini avant que l'IDP n'envoie un signal à l'aide de l'API Login Status. Lorsque l'état est unknown, le navigateur envoie une requête au point de terminaison des comptes de l'IDP et met à jour l'état en fonction de la réponse du point de terminaison des comptes.

Pour signaler 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 la méthode JavaScript navigator.login.setStatus('logged-in') à partir de l'origine de l'IDP dans une navigation de niveau supérieur:

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

L'état de connexion de l'utilisateur sera défini sur logged-in.

Pour signaler que l'utilisateur est déconnecté de tous ses comptes, envoyez un 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')

L'état de connexion de l'utilisateur sera défini sur logged-out.

L'état unknown est défini avant que l'IDP n'envoie un signal à l'aide de l'API Login Status. Le navigateur envoie une requête au point de terminaison des comptes de l'IDP 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, définissez l'état sur logged-out et échouez l'appel FedCM.

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

Même si l'IDP continue d'informer le navigateur de l'état de connexion de l'utilisateur, il peut être désynchronisé, par exemple lorsque la session expire. Le navigateur tente d'envoyer une requête authentifiée 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 ce cas, le navigateur peut permettre à l'utilisateur de se connecter dynamiquement à l'IDP via une fenêtre pop-up.

Implémenter FedCM en tant que RP

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
  } else {
    // FedCM is not supported, use a different identity solution
  }

Pour permettre aux utilisateurs de se connecter à l'IDP sur un RP à l'aide de FedCM, le RP peut appeler navigator.credentials.get(), par exemple:

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

Propriété de contexte

Avec la propriété context facultative, le RP peut modifier la chaîne dans l'UI de la boîte de dialogue FedCM (par exemple, "Se connecter à rp.example…", "Utiliser idp.example…") pour prendre en charge des contextes d'authentification prédéfinis, par exemple. La propriété context peut avoir les valeurs suivantes:

  • signin (par défaut)
  • signup
  • use
Schéma expliquant les composants de l'UI de la boîte de dialogue FedCM: une icône s'affiche en haut à gauche. À droite de l'icône se trouve un composant de contexte affichant le message "Se connecter à la RP avec l'IdP". En bas de l'écran se trouve un bouton "Continuer" avec un texte et une couleur d'arrière-plan personnalisés.
Comment le branding est appliqué à la boîte de dialogue FedCM

Par exemple, si vous définissez context sur use, le message suivant s'affiche:

Boîte de dialogue FedCM affichant un message contextuel personnalisé: au lieu de "Se connecter" avec FedCM, le message contextuel indique "Utiliser" FedCM.
Boîte de dialogue FedCM affichant un message contextuel personnalisé.

Le navigateur gère les cas d'utilisation de l'inscription et de la connexion différemment selon 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.
La propriété providers accepte un tableau d'objets IdentityProvider qui ont les propriétés suivantes:

Propriété "Providers"

La propriété providers accepte un tableau d'objets IdentityProvider qui présentent les propriétés suivantes:

Propriété Description
configURL (obligatoire) Chemin d'accès complet du fichier de configuration de l'IDP.
clientId (obligatoire) Identifiant client de l'RP, délivré par l'IdP.
nonce (facultatif) Chaîne aléatoire permettant de s'assurer que la réponse est émise pour cette requête 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é.
mode (facultatif) Chaîne spécifiant le mode d'UI de FedCM. Il peut s'agir de l'une des valeurs suivantes:
  • "active": la requête FedCM doit être déclenchée par une interaction de l'utilisateur (par exemple, un clic sur un bouton).
  • "passive": l'invite FedCM sera lancée sans interaction directe de l'utilisateur.
Consultez la page de présentation pour en savoir plus sur la différence entre les modes actif et passif.

Remarque: Le paramètre mode est compatible à partir de Chrome 132.
fields (facultatif) Tableau de chaînes qui spécifie les informations utilisateur ("name", "email", "picture") que l'RP doit demander à l'IdP de partager avec lui.
Remarque: L'API Field est compatible avec Chrome 132 et les versions ultérieures.
parameters (facultatif) Objet personnalisé permettant de spécifier des paramètres clé-valeur supplémentaires:
  • scope: valeur de chaîne contenant les autorisations supplémentaires que le RP doit demander, par exemple "drive.readonly calendar.readonly"
  • nonce: chaîne aléatoire pour s'assurer que la réponse est émise pour cette requête spécifique. Empêche les attaques par rejeu.
  • Autres paramètres de clé-valeur personnalisés.

Remarque: parameters est compatible à partir de Chrome 132.

Mode Actif

FedCM est compatible avec différentes configurations de mode UX. Le mode passif est le mode par défaut, et les développeurs n'ont pas besoin de le configurer.

Pour utiliser FedCM en mode actif:

  1. Vérifiez la disponibilité de la fonctionnalité dans le navigateur de l'utilisateur.
  2. Appelez l'API avec un geste utilisateur temporaire, tel qu'un clic sur un bouton.
  3. Transmettez le paramètre mode à l'appel d'API:
  let supportsFedCmMode = false;
  try {
    navigator.credentials.get({
      identity: Object.defineProperty(
        // Check if this Chrome version supports the Mode API.
        {}, 'mode', {
          get: function () { supportsFedCmMode = true; }
        }
      )
    });
  } catch(e) {}

  if (supportsFedCmMode) {
    // The button mode is supported. Call the API with mode property:
    return await navigator.credentials.get({
      identity: {
        providers: [{
          configURL: 'https://idp.example/config.json',
          clientId: '123',
        }],
        // The 'mode' value defines the UX mode of FedCM.
        // - 'active': Must be initiated by user interaction (e.g., clicking a button).
        // - 'passive': Can be initiated without direct user interaction.
        mode: 'active'
      }
    });
  }

Icône personnalisée en mode actif

Le mode actif permet aux fournisseurs d'identité d'inclure l'icône du logo officiel de l'RP directement dans la réponse du point de terminaison des métadonnées client. Le RP doit fournir ses données de branding à l'avance.

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

FedCM peut être appelé à partir d'un iFrame inter-origine à l'aide d'une règle d'autorisation identity-credentials-get, si le frame parent l'autorise. Pour ce faire, ajoutez l'attribut allow="identity-credentials-get" à la balise 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 limiter les origines pouvant appeler FedCM, il peut envoyer 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.

API Login Hint

À l'aide de l'indice de connexion, le RP peut recommander le compte avec lequel un utilisateur doit se connecter. Cela peut être utile pour réauthentifier les utilisateurs qui ne sont pas sûrs du compte qu'ils ont utilisé précédemment.

Les RP 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 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: '123',
        // Accounts endpoint can specify a 'login_hints' array for an account.
        // When RP specifies a 'exampleHint' value, only those accounts will be
        // shown to the user whose 'login_hints' array contains the 'exampleHint'
        // value
        loginHint : 'exampleHint'
      }]
    }
  });

Lorsqu'aucun compte ne correspond à loginHint, 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.

API Domain Hint

Les RP ne peuvent afficher de manière sélective que les comptes associés à un domaine donné. Cela peut être utile pour les RP limitées à un domaine d'entreprise.

Pour afficher uniquement des comptes de domaine spécifiques, le RP doit appeler 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 indiqué dans l'extrait de code suivant:

  return await navigator.credentials.get({
    identity: {
      providers: [{
        configURL: 'https://idp.example/manifest.json',
        clientId: 'abc',
        // Accounts endpoint can specify a 'domain_hints' array for an account.
        // When RP specifies a '@domain.example' value, only those accounts will be
        // shown to the user whose 'domain_hints' array contains the
        // '@domain.example' value
        domainHint : '@domain.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&#39;invite de connexion lorsqu&#39;aucun compte ne correspond à domainHint.
Exemple de requête de connexion lorsqu'aucun compte ne correspond à domainHint.

Paramètres personnalisés

La fonctionnalité de paramètres personnalisés permet au RP de fournir des paramètres clé-valeur supplémentaires au point de terminaison d'assertion d'identité. Avec l'API Parameters, les RP peuvent transmettre des paramètres supplémentaires à l'IDP pour demander des autorisations pour des ressources au-delà de la connexion de base. Transmettre des paramètres supplémentaires peut être utile dans les cas suivants:

  • Le RP doit demander dynamiquement des autorisations supplémentaires dont dispose l'IDP, telles que l'adresse de facturation ou l'accès au calendrier. L'utilisateur peut autoriser ces autorisations via un parcours UX contrôlé par l'IdP lancé à l'aide de la fonctionnalité Continuer. L'IdP partagera ensuite ces informations.

Pour utiliser l'API, le RP ajoute des paramètres à la propriété params en tant qu'objet dans l'appel navigator.credentials.get():

  let {token} = await navigator.credentials.get({
    identity: {
      providers: [{
        clientId: '1234',
        configURL: 'https://idp.example/fedcm.json',
        // Key/value pairs that need to be passed from the
        // RP to the IdP but that don't really play any role with
        // the browser.
        params: {
          IDP_SPECIFIC_PARAM: '1',
          foo: 'BAR'
        }
      },
    }
  });

Le navigateur traduit automatiquement cela en requête POST envoyée à l'IDP avec des paramètres sous la forme d'un seul objet sérialisé JSON encodé en URL:

  // The assertion endpoint is drawn from the config file
  POST /fedcm_assertion_endpoint HTTP/1.1
  Host: idp.example
  Origin: https://rp.example/
  Content-Type: application/x-www-form-urlencoded
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

  // params are translated into urlencoded version of `{"IDP_SPECIFIC_PARAM":"1","foo":"bar"}`
  account_id=123&client_id=client1234&params=%22%7B%5C%22IDP_SPECIFIC_PARAM%5C%22%3A1%2C%5C%22foo%5C%22%3A%5C%22BAR%5C%22%7D%22.

Si le RP a besoin d'autorisations supplémentaires, l'IDP peut fournir un lien de redirection. Par exemple, dans Node.js:

  if (rpRequestsPermissions) {
    // Response with a URL if the RP requests additional permissions
    return res.json({
      continue_on: '/example-redirect',
    });
  }

Champs

Le RP peut spécifier les informations utilisateur (toute combinaison de nom, d'adresse e-mail et de photo de profil) qu'il souhaite que l'IDP partage avec lui. Les informations demandées seront incluses dans l'UI de divulgation de la boîte de dialogue FedCM. L'utilisateur reçoit un message l'informant que idp.example partagera les informations demandées avec rp.example s'il choisit de se connecter.

Boîte de dialogue du mode actif FedCM affichant un message d&#39;information. Pour continuer, le fournisseur d&#39;identité partagera l&#39;adresse e-mail et la photo de profil de l&#39;utilisateur avec le site Web.
Message de divulgation en mode actif: le RP demande à l'IDP de ne partager que l'adresse e-mail et la photo de profil de l'utilisateur.

Pour utiliser la fonctionnalité Champs, le RP doit ajouter un tableau fields dans l'appel navigator.credentials.get(). Les champs peuvent contenir n'importe quelle permutation de name, email et picture. Il est possible d'étendre cette fonctionnalité à d'autres valeurs à l'avenir. Une requête avec fields se présente comme suit:

  let { token } = await navigator.credentials.get({
    identity: {
      providers: [{
        // RP requests the IdP to share only user email and profile picture
        fields: [ 'email', 'picture'],
        clientId: '1234',
        configURL: 'https://idp.example/fedcm.json',

      },
    }
  });

Le navigateur le traduit automatiquement en requête HTTP au point de terminaison d'assertion d'identité qui inclut le paramètre fields spécifié par le RP, avec les champs que le navigateur a divulgués à l'utilisateur dans un paramètre disclosure_shown_for. Pour assurer la rétrocompatibilité, le navigateur envoie également disclosure_text_shown=true si le texte d'information a été affiché et que les champs demandés incluent les trois champs: 'name', 'email' et 'picture'.

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

  // The RP only requested to share email and picture. The browser will send `disclosure_text_shown=false`, as the 'name' field value is missing
  account_id=123&client_id=client1234&disclosure_text_shown=false&fields=email,picture&disclosure_shown_for=email,picture

Si fields est un tableau vide, l'UI d'informations est ignorée par l'user-agent.

Boîte de dialogue du mode passif FedCM qui n&#39;affiche pas de message d&#39;information dans l&#39;UI.
Le message d'information n'est pas affiché en mode passif. Dans le flux de boutons, l'UI d'informations est entièrement ignorée.

Cela est vrai même si la réponse du point de terminaison des comptes ne contient pas d'ID client correspondant à l'RP dans approved_clients.

Dans ce cas, l'disclosure_text_shown envoyé au point de terminaison d'assertion d'ID est faux dans le corps HTTP:

  POST /id_assertion_endpoint HTTP/1.1
  Host: 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=234234&disclosure_text_shown=false

Afficher un message d'erreur

Il peut arriver 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 peut en informer l'utilisateur en affichant l'UI du 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 (ou "réauthn" en abrégé) permet aux utilisateurs de se réauthentifier automatiquement lorsqu'ils reviennent après leur authentification initiale à l'aide de FedCM. "Authentification initiale" signifie ici que l'utilisateur crée un compte ou se connecte au site Web de l'RP en appuyant sur le bouton Continuer en tant que… dans la boîte de dialogue de connexion de FedCM pour la première fois sur la même instance de navigateur.

Bien que l'expérience utilisateur explicite soit logique avant que l'utilisateur n'ait créé le compte fédéré pour empêcher le suivi (ce qui est l'un des principaux objectifs de FedCM), elle est inutilement lourde après que l'utilisateur l'a déjà effectuée une fois: une fois que l'utilisateur a accordé l'autorisation pour autoriser la communication entre le RP et l'IdP, il n'y a aucun avantage en termes de confidentialité ni de sécurité à appliquer une autre confirmation explicite de l'utilisateur pour quelque chose qu'il a déjà accepté auparavant.

Avec la réauthentification automatique, le navigateur modifie son comportement en fonction de l'option que vous spécifiez pour mediation lorsque vous appelez 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': nécessite toujours une médiation pour continuer, par exemple en cliquant sur le bouton "Continuer" dans l'UI. Sélectionnez cette option si vos utilisateurs doivent accorder une autorisation explicite chaque fois qu'ils doivent être authentifiés.
  • 'silent': réauthentification automatique si possible, échec silencieux sans médiation si ce n'est pas le cas. 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 actuellement non disponible pour FedCM.

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 globalement ni pour le RP 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 l'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, lorsqu'il n'est pas disponible, l'utilisateur peut être invité à se connecter avec une médiation utilisateur explicite, qui est un flux 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 expérience utilisateur très agréable. C'est pourquoi FedCM dispose d'un délai de 10 minutes après une réautorisation automatique pour éviter ce comportement. Cela signifie que la réauthentification automatique a lieu au maximum une fois toutes les 10 minutes, sauf si l'utilisateur se reconnecte dans ce délai. 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:

  • Dans Chrome pour ordinateur, accédez à chrome://password-manager/settings > Se connecter automatiquement.
  • Dans Chrome pour Android, ouvrez Paramètres > Gestionnaire de mots de passe > appuyez sur la 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 RP

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. Le RP peut déclencher une déconnexion en appelant la fonction IdentityCredential.disconnect(). Cette fonction peut être appelée à partir d'un frame RP de niveau supérieur. Le RP doit transmettre un configURL, le clientId qu'il utilise sous l'IdP et un accountHint pour que l'IdP 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 RP à l'aide de l'IdP via FedCM.
  • L'API est appelée à partir d'un iFrame sans stratégie d'autorisation FedCM.
  • La valeur configURL n'est pas valide ou le point de terminaison de déconnexion est manquant.
  • Échec de la vérification de la Content Security Policy (CSP).
  • Une demande de résiliation est en attente.
  • L'utilisateur a désactivé FedCM dans les paramètres du navigateur.

Lorsque le point de terminaison de déconnexion de l'IdP renvoie une réponse, le RP et l'IdP 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.