Mises à jour FedCM: Phases d'évaluation pour le bundle de l'API Continuation et octroi automatique de l'API Storage Access

À partir de Chrome 126, les développeurs peuvent commencer à exécuter une phase d'évaluation pour un ensemble de fonctionnalités de l'API Federated Credential Management (FedCM) pour ordinateur qui permettent certains cas d'utilisation de l'autorisation. Le bundle se compose de l'API Continuation et de l'API Parameters, qui permettent une expérience semblable à un flux d'autorisation OAuth impliquant une boîte de dialogue d'autorisation fournie par un fournisseur d'identité (IdP). Le bundle inclut également d'autres modifications telles que l'API Fields, plusieurs configURL et des libellés de compte personnalisés. À partir de Chrome 126, nous lançons également une phase d'évaluation pour l'API Storage Access (SAA) qui accorde automatiquement des requêtes SAA si l'utilisateur s'est connecté avec FedCM par le passé.

Phase d'évaluation: lot d'API FedCM Continuation

Le bundle de l'API FedCM Continuation se compose de plusieurs extensions FedCM:

API Continuation

Un utilisateur se connecte au tiers assujetti à des restrictions, puis donne une autorisation via le mode Bouton.

Vous pouvez regarder une démonstration de l'API sur Glitch.

L'API Continuation permet au point de terminaison d'assertion d'ID du fournisseur d'identité de renvoyer éventuellement une URL que FedCM affichera pour permettre à l'utilisateur de poursuivre un flux de connexion en plusieurs étapes. Cela permet au fournisseur d'identité de demander à l'utilisateur d'accorder à la partie de confiance des autorisations autres que celles qui sont possibles dans l'interface utilisateur FedCM existante, telles que l'accès aux ressources côté serveur de l'utilisateur.

En règle générale, le point de terminaison d'assertion d'ID renvoie un jeton requis pour l'authentification.

{
  "token": "***********"
}

Toutefois, avec l'API Continuation, le point de terminaison d'assertion d'ID peut renvoyer une propriété continue_on qui inclut un chemin d'accès absolu ou relatif vers le point de terminaison de l'assertion d'ID.

{
  // In the id_assertion_endpoint, instead of returning a typical
  // "token" response, the IdP decides that it needs the user to
  // continue on a pop-up window:
  "continue_on": "/oauth/authorize?scope=..."
}

Dès que le navigateur reçoit la réponse continue_on, une nouvelle fenêtre pop-up s'ouvre et redirige l'utilisateur vers le chemin spécifié.

Une fois que l'utilisateur a interagi avec la page, par exemple en accordant d'autres autorisations pour partager des informations supplémentaires avec la RP, la page du fournisseur d'identité peut appeler IdentityProvider.resolve() pour résoudre l'appel navigator.credentials.get() d'origine et renvoyer un jeton en tant qu'argument.

document.getElementById('allow_btn').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 fermera alors le pop-up et renverra le jeton à l'appelant de l'API.

Si l'utilisateur refuse la requête, vous pouvez fermer la fenêtre en appelant IdentityProvider.close().

IdentityProvider.close();

Si, pour une raison quelconque, l'utilisateur a modifié son compte dans la fenêtre pop-up (par exemple, le fournisseur d'identité propose une fonction "changer d'utilisateur" ou dans les cas de délégation), l'appel de résolution accepte un second argument facultatif qui autorise un élément semblable à celui-ci:

IdentityProvider.resolve(token, {accountId: '1234');

API Parameters

L'API Parameters permet à la RP de fournir des paramètres supplémentaires au point de terminaison d'assertion d'ID. Avec l'API Parameters, les RP peuvent transmettre des paramètres supplémentaires au fournisseur d'identité afin de demander des autorisations pour des ressources autres que la connexion de base. L'utilisateur autorise ces autorisations via un flux d'expérience utilisateur contrôlé par l'IdP, qui est lancé via l'API Continuation.

Pour utiliser l'API, ajoutez 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',
        ETC: 'MOAR',
        scope: 'calendar.readonly photos.write',
      }
    },
  }
});

Les noms de propriété de l'objet params sont précédés de param_. Dans l'exemple ci-dessus, la propriété "params" contient IDP_SPECIFIC_PARAM en tant que '1', foo en tant que 'BAR', ETC en tant que 'MOAR' et scope en tant que 'calendar.readonly photos.write'. Il sera traduit par param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write dans le corps HTTP de la requête:

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

account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false&param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write

Obtenir les autorisations de manière dynamique

En général, il est plus utile pour les utilisateurs de demander des autorisations lorsque cela est nécessaire, plutôt que lorsque le développeur estime qu'elles sont plus faciles à implémenter. Par exemple, il est préférable de demander l'autorisation d'accéder à un appareil photo lorsque l'utilisateur est sur le point de prendre une photo que de demander l'autorisation dès qu'il accède au site Web. La même pratique s'applique aux ressources de serveur. Ne demandez les autorisations que lorsqu'elles sont nécessaires pour l'utilisateur. C'est ce qu'on appelle l'"autorisation dynamique".

Pour demander l'autorisation de manière dynamique avec FedCM, le fournisseur d'identité peut:

  1. Appelez navigator.credentials.get() avec les paramètres requis que le fournisseur d'identité peut comprendre, tels que scope.
  2. Le point de terminaison de l'assertion d'ID confirme que l'utilisateur est déjà connecté et répond avec une URL continue_on.
  3. Le navigateur ouvre une fenêtre pop-up sur la page des autorisations de l'IdP demandant une autorisation supplémentaire correspondant aux champs d'application demandés.
  4. Une fois autorisée via IdentityProvider.resolve() par le fournisseur d'identité, la fenêtre est fermée et l'appel navigator.credentials.get() d'origine de la RP obtient un jeton approprié ou un code d'autorisation afin que la RP puisse l'échanger avec un jeton d'accès approprié.

API Fields

L'API Fields permet à la RP de déclarer des attributs de compte à demander au fournisseur d'identité afin que le navigateur puisse afficher une UI de divulgation appropriée dans la boîte de dialogue FedCM. Il appartient au fournisseur d'identité d'inclure les champs demandés dans le jeton renvoyé. Envisagez de demander un "profil de base" dans OpenID Connect plutôt que des "champs d'application" dans OAuth.

Message de divulgation en mode widget.
Message de divulgation en mode widget.
Message de divulgation en mode bouton.
Message de divulgation en mode bouton.

Pour utiliser l'API Fields, ajoutez des paramètres à la propriété fields en tant que tableau dans l'appel navigator.credentials.get(). Les champs peuvent contenir 'name', 'email' et 'picture' pour le moment, mais ils peuvent être développés pour inclure d'autres valeurs à l'avenir.

Une requête avec fields ressemblerait à ceci:

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      fields: ['name', 'email', 'picture'],
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      params: {
        scope: 'drive.readonly calendar.readonly',
      }
    },
  }
  mediation: 'optional',
});

La requête HTTP envoyée au point de terminaison de l'assertion d'ID inclut le paramètre fields spécifié par la RP, avec le paramètre disclosure_text_shown défini sur true s'il ne s'agit pas d'un utilisateur connu, ainsi que les champs que le navigateur a divulgués à l'utilisateur dans un paramètre disclosure_shown_for:

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=true&fields=email,name,picture&disclosure_shown_for=email,name,picture

Si la RP a besoin d'accéder à des données supplémentaires du fournisseur d'identité, telles que l'accès à un agenda, cela doit être géré avec un paramètre personnalisé, comme indiqué ci-dessus. Le fournisseur d'identité renvoie une URL continue_on pour demander l'autorisation.

Si fields est un tableau vide, la requête se présente comme suit:

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      fields: [],
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      params: {
        scope: 'drive.readonly calendar.readonly',
      }
    },
  }
  mediation: 'optional',
});

Si fields est un tableau vide, le user-agent ignore l'interface utilisateur de divulgation.

Le message de divulgation ne s'affiche pas en mode widget. Lors du flux du bouton, l'interface utilisateur du communiqué est complètement ignorée.
Le message de divulgation ne s'affiche pas en mode widget. Lors du parcours du bouton, l'interface utilisateur du communiqué est complètement ignorée.

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

Dans ce cas, le disclosure_text_shown envoyé au point de terminaison de l'assertion d'ID est défini sur "false" 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

Plusieurs configURL

L'utilisation de plusieurs configURL permet aux fournisseurs d'identité d'accepter plusieurs fichiers de configuration, en spécifiant accounts_endpoint et login_url dans le fichier connu de la même manière que dans les fichiers de configuration.

Si accounts_endpoint et login_url sont ajoutés au fichier well-known, les provider_urls sont ignorés afin que le fournisseur d'identité puisse prendre en charge plusieurs fichiers de configuration. Si ce n'est pas le cas, provider_urls continue de s'appliquer afin d'être rétrocompatible.

Le fichier bien connu qui prend en charge plusieurs configURL peut se présenter comme suit:

{
  "provider_urls": [ "https://idp.example/fedcm.json" ],
  "accounts_endpoint": "https://idp.example/accounts",
  "login_url": "https://idp.example/login"
}

que nous utilisons aux fins suivantes :

  1. Assurez la rétrocompatibilité avec les fichiers connus existants et la version antérieure des navigateurs déjà déployés.
  2. disposer d'un nombre arbitraire de fichiers de configuration, à condition qu'ils pointent tous vers les mêmes accounts_endpoint et login_url ;
  3. Vous n'avez pas la possibilité d'ajouter l'entropie à la requête d'extraction avec identifiants effectuée à accounts_endpoint, car elle doit être spécifiée au niveau ".well-known".

La prise en charge de plusieurs configURL est facultative et les implémentations FedCM existantes peuvent rester les mêmes.

Libellés de compte personnalisés

Les libellés de compte personnalisés permettent aux fournisseurs d'identité FedCM d'annoter les comptes afin que les tiers assujettis à des restrictions puissent les filtrer en spécifiant le libellé dans un fichier de configuration. Un filtrage similaire a été possible en utilisant l'API Domain Hint et l'API Login Hint 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 configURL sont utilisées. Les étiquettes de compte personnalisées sont également différentes dans la mesure où elles sont fournies par le serveur IdP, et non par la RP, comme les identifiants de connexion ou de domaine.

Exemple

Un IdP est compatible avec deux URL de configuration (configURL) pour le grand public et pour l'entreprise, respectivement. Le fichier de configuration consommateur porte le libellé 'consumer' et le fichier de configuration de l'entreprise le libellé 'enterprise'.

Avec une telle configuration, le fichier bien connu inclut accounts_endpoint et login_url pour autoriser plusieurs configURL.

{
  "provider_urls": [ "https://idp.example/fedcm.json" ],
  "accounts_endpoint": "https://idp.example/accounts",
  "login_url": "https://idp.example/login"
}

Lorsque les accounts_endpoint sont fournies dans le fichier well-known, les provider_urls sont ignorées. La RP peut pointer directement vers les fichiers de configuration respectifs dans l'appel navigator.credentials.get().

Le fichier de configuration du consommateur se trouve à l'emplacement https://idp.example/fedcm.json, qui inclut la propriété accounts qui spécifie 'consumer' à l'aide de include.

{
  "accounts_endpoint": "https://idp.example/accounts",
  "client_metadata_endpoint": "/client_metadata",
  "login_url": "https://idp.example/login",
  "id_assertion_endpoint": "/assertion",
  "accounts": {
    "include": "consumer"
  }
}

Le fichier de configuration d'entreprise se trouve à l'emplacement https://idp.example/enterprise/fedcm.json, qui inclut la propriété accounts qui spécifie 'enterprise' à l'aide de include.

{
  "accounts_endpoint": "https://idp.example/accounts",
  "client_metadata_endpoint": "/enterprise/client_metadata",
  "login_url": "https://idp.example/login",
  "id_assertion_endpoint": "/assertion",
  "accounts": {
    "include": "enterprise"
  }
}

Le point de terminaison des comptes de fournisseur d'identité commun (dans cet exemple https://idp.example/accounts) renvoie une liste de comptes incluant une propriété de libellés avec labels attribuée dans un tableau pour chaque compte. Voici un exemple de réponse pour un utilisateur disposant de deux comptes. un pour le grand public et l'autre pour les entreprises:

{
 "accounts": [{
   "id": "123",
   "given_name": "John",
   "name": "John Doe",
   "email": "john_doe@idp.example",
   "picture": "https://idp.example/profile/123",
   "labels": ["consumer"]
  }], [{
   "id": "4567",
   "given_name": "Jane",
   "name": "Jane Doe",
   "email": "jane_doe@idp.example",
   "picture": "https://idp.example/profile/4567",
   "labels": ["enterprise"]
  }]
}

Lorsqu'un tiers assujetti à des restrictions souhaite autoriser les utilisateurs de 'enterprise' à se connecter, il peut spécifier l'URL configURL 'enterprise' 'https://idp.example/enterprise/fedcm.json' dans l'appel navigator.credentials.get():

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      clientId: '1234',
      nonce: '234234',
      configURL: 'https://idp.example/enterprise/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é en mode silencieux par le navigateur afin que l'utilisateur ne dispose pas d'un compte non compatible avec l'IdP sur ce site.

Phase d'évaluation: FedCM comme signal de confiance pour l'API Storage Access

Chrome 126 lance une phase d'évaluation de FedCM en tant que signal de confiance pour l'API Storage Access. Avec cette modification, une autorisation préalable accordée via FedCM devient une raison valable d'approuver automatiquement une demande d'accès au stockage par les API Storage Access.

Cette option est utile lorsqu'un iFrame intégré souhaite accéder à des ressources personnalisées (par exemple, si idp.example est intégré à rp.example et qu'il doit afficher une ressource personnalisée). Si le navigateur limite l'accès aux cookies tiers, même si l'utilisateur est connecté à rp.example à l'aide de idp.example avec FedCM, l'iFrame idp.example intégré ne pourra pas demander de ressources personnalisées, car les requêtes n'incluront pas de cookies tiers.

Pour ce faire, idp.example doit obtenir une autorisation d'accès au stockage via son iFrame intégré au site Web. Cette autorisation ne peut être obtenue que via une invite d'autorisation.

Avec FedCM comme signal de confiance pour l'API Storage Access, les vérifications d'autorisation de l'API Storage Access acceptent non seulement l'octroi d'autorisation donné par une invite d'accès au stockage, mais aussi l'autorisation accordée par une invite FedCM.

// In top-level rp.example:

// Ensure FedCM permission has been granted.
const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://idp.example/fedcm.json',
      clientId: '123',
    }],
  },
  mediation: 'optional',
});

// In an embedded IdP iframe:

// No user gesture is needed to call this, and the call will be auto-granted.
await document.requestStorageAccess();

// This returns `true`.
const hasAccess = await document.hasStorageAccess();

Une fois l'utilisateur connecté à FedCM, l'autorisation est automatiquement accordée tant que l'authentification FedCM est active. Cela signifie qu'une fois l'utilisateur déconnecté, une invite s'affiche lorsque l'utilisateur demande l'autorisation.

Participer à la phase d'évaluation

Vous pouvez essayer le bundle d'API FedCM Continuation localement en activant un indicateur Chrome chrome://flags#fedcm-authz dans Chrome 126 ou version ultérieure. Vous pouvez également tester FedCM en tant que signal de confiance pour l'API Storage Access localement en activant #fedcm-with-storage-access-api dans Chrome 126 ou version ultérieure.

Ces fonctionnalités sont également disponibles en phase d'évaluation. Les phases d'évaluation vous permettent de tester de nouvelles fonctionnalités et de donner votre avis sur leur facilité d'utilisation, leur utilité et leur efficacité. Pour en savoir plus, consultez Premiers pas avec les phases d'évaluation.

Pour essayer l'essai d'origine du bundle de l'API FedCM Continuation, créez deux jetons d'évaluation d'origine:

Si vous souhaitez activer l'API Continuation avec le flux de boutons, activez également l'essai d'origine de l'API Button Mode:

Pour essayer FedCM en tant que signal de confiance pour l'essai Origin Trial de l'API Storage Access:

La phase d'évaluation du bundle d'API Continuation et FedCM en tant que signal de confiance pour la phase d'évaluation de l'API Storage Access sont disponibles à partir de Chrome 126.

Enregistrer une phase d'évaluation tierce pour le tiers assujetti à des restrictions

  1. Accédez à la page d'inscription à la phase d'évaluation.
  2. Cliquez sur le bouton Register (S'inscrire), puis remplissez le formulaire pour demander un jeton.
  3. Saisissez l'origine du fournisseur d'identité (IdP) sur Web Origin (Origine Web).
  4. Cochez la case "Correspondance tierce" pour injecter le jeton avec JavaScript sur d'autres origines.
  5. Cliquez sur Envoyer.
  6. Intégrez le jeton émis à un site Web tiers.

Pour intégrer le jeton sur un site Web tiers, ajoutez le code suivant à la bibliothèque JavaScript ou au SDK du fournisseur d'identité diffusé à partir de son origine.

const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);

Remplacez TOKEN_GOES_HERE par votre propre jeton.