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é.

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.

Pour en savoir plus sur les cas d'utilisation, les parcours utilisateur et la feuille de route de l'API FedCM, 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 ordinateur, suivez les instructions de la section Déboguer à distance des appareils Android.

Bloquer les cookies tiers dans Chrome

Bloquer les cookies tiers dans les paramètres de Chrome
Bloquer les cookies tiers dans les paramètres de Chrome

Vous pouvez tester le fonctionnement de FedCM sans cookies tiers dans Chrome avant qu'il ne soit appliqué.

Pour bloquer les cookies tiers, utilisez le mode navigation privée ou sélectionnez "Bloquer les cookies tiers" dans les paramètres de votre ordinateur à l'adresse 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 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.

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"]
}

Le fichier JSON doit contenir la propriété provider_urls avec un tableau d'URL de fichier de configuration de l'IDP pouvant être spécifiées en tant que partie de 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 peut changer à l'avenir 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 une liste des points de terminaison requis pour le navigateur. Les IdP hébergeront 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;

Spécifiez une 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'identité.
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) Option de branding 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. Les images SVG ne sont pas compatibles.
  • 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 à l'aide de 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 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 de l'IDP

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.php 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.

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 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 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é de la RP.
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'identité du fournisseur d'identité 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.
nonce (facultatif) Nonce de requête, fourni par le RP.
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" 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 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.

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

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.

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 au RP par le navigateur afin que le RP 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'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"
  }
}

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.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

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 "*".

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 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 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é 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 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 sous la forme 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 déjà s'être connecté à l'IDP au moment de la publication de cette API. Il est possible que l'IDP n'ait pas la possibilité de le signaler au navigateur au moment de l'appel initial de FedCM. Dans ce cas, Chrome envoie une requête au point de terminaison de comptes de l'IDP et met à jour l'état en fonction de la réponse du point de terminaison de 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.

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 aux utilisateurs de se connecter à l'IDP à partir de l'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 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é.

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 au RP.
Un utilisateur se connecte à un RP à l'aide de FedCM.

Lorsque le 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 est envoyée au point de terminaison d'assertion d'identité au fournisseur d'identité pour récupérer un jeton.
  4. Le RP peut valider le jeton pour authentifier l'utilisateur.
Appel d'API de connexion
appel d'API de connexion

Les RP doivent prendre en charge les navigateurs qui ne sont pas compatibles avec FedCM. Par conséquent, les utilisateurs doivent pouvoir utiliser un processus de connexion existant qui n'utilise pas FedCM. Tant que les cookies tiers ne seront plus disponibles dans les navigateurs, cela ne devrait pas poser de problème.

Une fois le jeton validé par le serveur de RP, la RP peut enregistrer l'utilisateur ou le laisser 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 peut ne pas être sûr du compte qu'il a utilisé. Si le RP peut spécifier le compte avec lequel se connecter, l'utilisateur pourra choisir plus facilement un compte.

Les RP peuvent afficher sélectivement un compte spécifique 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",
      nonce: nonce,
      loginHint : "demo1@example.com"
    }]
  }
});

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

Il arrive que le RP sache déjà que seuls les comptes associés à un certain domaine sont autorisés à se connecter au site. Cela est particulièrement courant dans les scénarios d'entreprise où le site auquel on accède 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 évite les scénarios où un utilisateur tente de se connecter à la RP à l'aide d'un compte en dehors du domaine de l'entreprise, pour recevoir un message d'erreur plus tard (ou un silence si la connexion n'a pas fonctionné) parce que le bon type de compte 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 (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 un délai de 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:

  • 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.

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.