FedCM-Updates: Ursprungstests für das Continuation API-Bundle und die automatische Zuweisung der Storage Access API

Ab Chrome 126 können Entwickler einen Ursprungstest für ein Bundle von Desktop-Funktionen der Federated Credential Management API (FedCM), die einige Anwendungsfälle für die Autorisierung Das Bundle besteht aus der Continuation API und dem Parameters API, die einen OAuth-Autorisierungsablauf ermöglicht über ein Dialogfeld mit Berechtigungen, die vom Identitätsanbieter (Identity Provider, IdP) bereitgestellt werden. Das Paket enthält andere Änderungen wie die Fields API, Multiple configURLs und Custom Kontolabels. Ab Chrome 126 führen wir auch einen Ursprungstest für die Storage Access API (SAA), die SAA-Anfragen automatisch gewährt, wenn der Nutzer in der Vergangenheit erfolgreich mit FedCM angemeldet.

Ursprungstest: FedCM Continuation API-Bundle

Das FedCM Continuation API-Paket besteht aus mehreren FedCM-Erweiterungen:

Continuation API

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
Ein Nutzer meldet sich beim RP an und autorisiert ihn dann über den Schaltflächenmodus.

Du kannst dir eine Demo der API auf Glitch ansehen.

Die Continuation API ermöglicht das IdP-ID-Assertion Endpunkt zu optional eine URL zurückgeben, die FedCM rendert, damit der Nutzer Anmeldung in mehreren Schritten Dadurch kann der IdP den Nutzer um die Erteilung des die über die bestehende FedCM-Benutzeroberfläche hinausgehen, etwa Zugriff auf die serverseitigen Ressourcen des Nutzers.

Normalerweise gibt der ID-Assertion-Endpunkt ein Token zurück, das für Authentifizierung.

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

Mit der Continuation API kann jedoch die ID-Assertion Endpunkt kann continue_on-Eigenschaft zurückgeben, die einen absoluten oder relativen Pfad enthält Pfad zum ID-Assertion-Endpunkt.

{
  // 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=..."
}

Sobald der Browser die continue_on-Antwort erhält, öffnet sich ein neues Pop-up-Fenster. und navigiert den Nutzer zum angegebenen Pfad.

Nachdem der Nutzer mit der Seite interagiert hat, z. B. indem er weitere Berechtigungen gewährt um zusätzliche Informationen mit dem RP zu teilen, kann die IdP-Seite IdentityProvider.resolve(), um das Original aufzulösen navigator.credentials.get() ruft ein Token auf und gibt ein Token als Argument zurück.

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);
});

Der Browser schließt dann das Pop-up und gibt das Token an die API zurück. Anrufer.

Wenn der Nutzer die Anfrage ablehnt, können Sie das Fenster schließen, indem Sie folgenden Befehl aufrufen: IdentityProvider.close()

IdentityProvider.close();

Wenn der Nutzer sein Konto im Pop-up geändert hat (z. B. bietet der IdP einen „Wechselnutzer“ an, oder in Delegationsfällen), die Lösung verwendet ein optionales zweites Argument, das etwa Folgendes zulässt:

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

Parameter-API

Die Parameters API ermöglicht die RP um zusätzliche Parameter für die ID-Assertion bereitzustellen Endpunkt. Mit der Parameters API können RPs zusätzliche Parameter an den IdP weitergeben, Berechtigungen für Ressourcen anfordern, die über die einfache Anmeldung hinausgehen Der Nutzer autorisiert dann über einen IdP-gesteuerten UX-Ablauf, der über die Continuation API.

Wenn Sie die API verwenden möchten, fügen Sie der Eigenschaft params Parameter als Objekt im Anruf in 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',
      }
    },
  }
});

Den Attributnamen im params-Objekt wird das Präfix param_ vorangestellt. Im im Beispiel oben enthält die Eigenschaft "params" IDP_SPECIFIC_PARAM als '1', foo. als 'BAR', ETC als 'MOAR' und scope als 'calendar.readonly photos.write'. Dies wird übersetzt als param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write im HTTP-Text der Anfrage:

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

Berechtigungen dynamisch abrufen

Im Allgemeinen ist es für Nutzer am hilfreichsten, Berechtigungen anzufordern, wenn sie erforderlich sind, als wenn der Entwickler der Meinung ist, dass die Implementierung am einfachsten ist. Für zum Beispiel um Zugriff auf eine Kamera zu gewähren, wenn der Nutzer wird der Nutzer am besten um Erlaubnis gefragt, Website. Dasselbe gilt für Serverressourcen. Nur Berechtigungen anfordern wenn sie für die Nutzenden gebraucht werden. Dies wird als „dynamische Autorisierung“ bezeichnet.

Für eine dynamische Autorisierung mit FedCM kann der IdP Folgendes tun:

  1. navigator.credentials.get() mit den erforderlichen Parametern aufrufen, die der IdP kann zu verstehen, z. B. scope.
  2. Die ID-Assertion Endpunkt bestätigt, dass der Nutzer bereits angemeldet ist, und antwortet mit einer continue_on-URL.
  3. Im Browser wird ein Pop-up-Fenster mit der Berechtigungsseite des IdP geöffnet. zusätzliche Berechtigung, die den angeforderten Bereichen entspricht.
  4. Nach der Autorisierung über IdentityProvider.resolve() vom IdP ist das Zeitfenster und der ursprüngliche navigator.credentials.get()-Aufruf des RP erhält eine ein relevantes Token oder einen Autorisierungscode, damit der RP ihn mit einem das richtige Zugriffstoken.

Fields API

Mit der Fields API kann das RP folgende Aktionen ausführen: die vom IdP anzufordernden Kontoattribute deklarieren, damit der Browser eine ordnungsgemäße Offenlegungs-UI im FedCM-Dialogfeld rendern ist der IdP um die angeforderten Felder in das zurückgegebene Token aufzunehmen. Diese Anforderung könnte sinnvoll sein ein „einfaches Profil“ in OpenID Connect im Vergleich zu "Bereichen" in OAuth.

<ph type="x-smartling-placeholder">
</ph> Offenlegungsmeldung im Widget-Modus.
Hinweis zur Offenlegung im Widget-Modus.
<ph type="x-smartling-placeholder">
</ph> Offenlegungsmitteilung im Schaltflächenmodus.
Hinweis zur Offenlegung im Schaltflächenmodus.

Wenn Sie die Fields API verwenden möchten, fügen Sie dem Attribut fields Parameter als Array im Anruf in navigator.credentials.get(). Die Felder können 'name' und 'email' enthalten. und 'picture', kann aber für den Parameter zu entwickeln.

Eine Anfrage mit fields würde so aussehen:

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',
});

Die HTTP-Anfrage an die ID-Assertion Endpunkt enthält den RP-spezifischen fields-Parameter mit dem disclosure_text_shown auf true gesetzt ist, wenn es sich nicht um einen wiederkehrenden Nutzer handelt, und die Felder, Browser, der dem Nutzer in einem disclosure_shown_for-Parameter offengelegt wird:

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

Wenn der RP Zugriff auf zusätzliche Daten vom IdP benötigt, z. B. auf einen Kalender, sollte dies wie oben beschrieben mit einem benutzerdefinierten Parameter behandelt werden. Die Der IdP gibt eine continue_on-URL zurück, um die Berechtigung anzufordern.

Wenn fields ein leeres Array ist, würde die Anfrage so aussehen:

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',
});

Wenn fields ein leeres Array ist, überspringt der User-Agent die Offenlegungs-UI.

<ph type="x-smartling-placeholder">
</ph> Offenlegungsmeldung wird im Widget-Modus nicht angezeigt. Beim Schaltflächenablauf wird die Benutzeroberfläche zur Offenlegung vollständig übersprungen.
Offenlegungsmeldung wird im Widget-Modus nicht angezeigt. Beim Ablauf der Schaltflächen wird die Benutzeroberfläche zur Offenlegung vollständig übersprungen.

Dies ist selbst dann der Fall, wenn die Antwort der accounts Endpunkt enthält keine Client-ID, die dem RP in approved_clients entspricht.

In diesem Fall wurde das an die ID-Assertion gesendete disclosure_text_shown Endpunkt ist "false" im HTTP-Text ein:

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

Mehrere configURLs

Mehrere configURLs ermöglichen IdPs mehrere Konfigurationsdateien für einen IdP unterbringen, indem Sie accounts_endpoint und login_url im bekannten dieselbe Datei wie die Konfigurationsdateien.

Wenn accounts_endpoint und login_url der bekannten Datei hinzugefügt werden, gibt der Parameter provider_urls werden ignoriert, damit der IdP mehrere Konfigurationsdateien unterstützen kann. Ist dies nicht der Fall, werden provider_urls weiterhin wirksam, sodass die Änderung rückwärts erfolgt. kompatibel sind.

Eine bekannte Datei, die mehrere configURLs unterstützt, kann wie folgt aussehen:

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

Dies ermöglicht uns Folgendes:

  1. Die Abwärts- und Vorwärtskompatibilität mit bereits bekannten Dateien wird aufrechterhalten. und die frühere Version von Browsern, die bereits bereits im Internet eingesetzt werden.
  2. Beliebig viele Konfigurationsdateien haben, solange sie alle auf den accounts_endpoint und login_url sind identisch.
  3. Keine Möglichkeit, der Abrufanfrage für Anmeldedaten eine Entropie hinzuzufügen an die accounts_endpoint übergeben werden, da dies im Feld „.well-known“

Die Unterstützung mehrerer configURLs ist optional und die bestehende FedCM-Richtlinie Implementierungen gleich bleiben.

Benutzerdefinierte Kontolabels

Benutzerdefinierte Kontolabels ermöglichen FedCM IdPs können Konten annotieren, damit RPs sie filtern können, indem sie das Label in eine Konfigurationsdatei. Eine ähnliche Filterung ist mit dem Domain-Hinweis möglich. API und das Login Hint API durch Angabe von im navigator.credentials.get()-Aufruf verwenden, aber die benutzerdefinierten Kontolabels Sie können Nutzer filtern, indem Sie die Konfigurationsdatei angeben. Dies ist besonders nützlich, mehrere configURLs werden verwendet. Benutzerdefinierte Kontolabels sind unterscheiden sich auch darin, dass sie vom IdP-Server bereitgestellt werden, z. B. Anmelde- oder Domainhinweise.

Beispiel

Ein IdP unterstützt zwei configURLs für Nutzer bzw. Unternehmen. Die Nutzerkonfigurationsdatei hat das Label 'consumer' und die Unternehmenskonfigurationsdatei hat das Label 'enterprise'.

Bei einer solchen Konfiguration enthält die bekannte Datei accounts_endpoint und login_url, um mehrere configURLs zuzulassen.

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

Wenn accounts_endpoint in der bekannten Datei bereitgestellt wird, provider_urls werden ignoriert. Der RP kann direkt auf die entsprechende Konfiguration verweisen. Dateien im navigator.credentials.get()-Aufruf.

Die Nutzerkonfigurationsdatei befindet sich unter https://idp.example/fedcm.json und enthält Folgendes: accounts-Eigenschaft, die 'consumer' mithilfe von include angibt.

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

Die Unternehmenskonfigurationsdatei befindet sich unter https://idp.example/enterprise/fedcm.json, Sie enthält die Eigenschaft accounts, die 'enterprise' angibt, indem die 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"
  }
}

Gemeinsame IdP-Konten Endpunkt (in diesem Beispiel https://idp.example/accounts) gibt eine Liste der Konten zurück, enthält eine Labels-Property mit zugewiesener labels in einem Array für jedes Konto. Das folgende Beispiel zeigt eine Antwort für einen Nutzer mit zwei Konten. Eines ist für Privatnutzer und der andere für Unternehmen:

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

Wenn ein RP Nutzern die Anmeldung von 'enterprise' erlauben möchte, können sie die 'enterprise' configURL 'https://idp.example/enterprise/fedcm.json' im navigator.credentials.get()-Anruf:

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

Daher steht dem Nutzer nur die Konto-ID von '4567' zur Verfügung . Die Konto-ID von '123' wird vom Browser automatisch ausgeblendet, damit der Nutzer erhält kein Konto, das nicht vom IdP auf dieser Website unterstützt wird.

Ursprungstest: FedCM als Vertrauenssignal für die Storage Access API

Chrome 126 startet einen Ursprungstest von FedCM als Vertrauenssignal für die Speicherzugriff API hinzu. Mit ist eine vorherige Erteilung von Berechtigungen über FedCM ein gültiger Grund dafür, automatisch eine Speicherzugriffsanforderung durch den Speicherzugriff APIs

Dies ist nützlich, wenn ein eingebetteter iFrame auf personalisierte Ressourcen zugreifen möchte: Wenn z. B. idp.example in rp.example eingebettet ist und ein personalisierte Ressource. Wenn der Browser den Zugriff auf Drittanbieter-Cookies einschränkt, Auch wenn der Nutzer bei rp.example über idp.example mit FedCM angemeldet ist, eingebetteter idp.example iFrame können keine personalisierten Ressourcen anfordern da Anfragen keine Drittanbieter-Cookies enthalten.

Dafür benötigt idp.example über die iFrame, den Sie auf der Website eingebettet haben. Dies ist nur über eine Berechtigungsaufforderung.

Mit FedCM als Vertrauenssignal für den Speicherzugriff API Bei Berechtigungsprüfungen der Storage Access API wird nicht nur die gewährte Berechtigung akzeptiert, wird durch eine Aufforderung für den Speicherzugriff erteilt, aber auch die gewährte Berechtigung durch eine FedCM-Aufforderung.

// 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();

Sobald der Nutzer in FedCM angemeldet ist, wird die Berechtigung automatisch gewährt, solange die FedCM-Authentifizierung aktiv ist. Wenn also der Nutzer getrennt wurde, um eine Berechtigung anzufordern.

Am Ursprungstest teilnehmen

Sie können das FedCM Continuation API-Bundle lokal testen, indem Sie einen Chrome-Browser melden chrome://flags#fedcm-authz ab Chrome 126. Sie können auch die FedCM ausprobieren als Vertrauenssignal für die Storage Access API zu verwenden, #fedcm-with-storage-access-api ab Chrome 126.

Diese Funktionen sind auch als Ursprungstests verfügbar. Mit Ursprungstests können Sie neue Funktionen ausprobieren und Feedback zu ihrer Nutzerfreundlichkeit, Funktionalität und Effektivität geben. Weitere Informationen finden Sie unter Erste Schritte mit Ursprungstests.

Ursprung des FedCM Continuation API-Bundles testen Testversion, Erstellen Sie zwei Ursprungstest-Tokens:

Wenn Sie die Continuation API zusammen mit der Schaltfläche , aktiviere den Schaltflächenmodus API-Ursprung Testzeitraum Außerdem:

FedCM als Vertrauenssignal für den Ursprung der Storage Access API testen Testversion:

Der Continuation API-Ursprungstest im Paket und FedCM als Vertrauenssignal für die Storage Access API-Ursprungstests sind ab Chrome 126 verfügbar.

Ursprungstest eines Drittanbieters für die RP registrieren

  1. Rufen Sie die Registrierungsseite für den Ursprungstest auf.
  2. Klicken Sie auf die Schaltfläche Registrieren und füllen Sie das Formular aus, um ein Token anzufordern.
  3. Geben Sie den Ursprung des IdP als Web Origin (Web-Ursprung) ein.
  4. Aktivieren Sie den Drittanbieterabgleich, um das Token mit JavaScript aus anderen Quellen zu injizieren.
  5. Klicken Sie auf Senden.
  6. Betten Sie das ausgestellte Token auf der Website eines Drittanbieters ein.

Um das Token auf der Website eines Drittanbieters einzubetten, fügen Sie den folgenden Code in das Feld JavaScript-Bibliothek oder SDK, die vom Ursprung des IdP bereitgestellt wird.

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

Ersetzen Sie TOKEN_GOES_HERE durch Ihr eigenes Token.