Identitätslösung mit FedCM auf Identitätsanbieterseite implementieren

Die FedCM umfasst mehrere wichtige Schritte sowohl für den Identitätsanbieter (Identity Provider, IdP) als auch für die Anwendung (Relying Party, RP). Weitere Informationen zur Implementierung von FedCM auf der Seite des RP finden Sie in der Dokumentation.

IdPs müssen die folgenden Schritte ausführen, um FedCM zu implementieren:

.well-known-Datei erstellen

Um zu verhindern, dass Tracker die API missbrauchen, muss eine .well-known-Datei von /.well-known/web-identity der eTLD+1 des IdP ausgeliefert werden.

Die bekannte Datei kann die folgenden Properties enthalten:

Attribut Erforderlich Beschreibung
provider_urls erforderlich Array von Pfaden zu IdP-Konfigurationsdateien. Wird ignoriert (ist aber trotzdem erforderlich), wenn accounts_endpoint und login_url angegeben sind.
accounts_endpoint empfohlen, erfordert login_url
URL für den Endpunkt „Konten“. So ist die Unterstützung mehrerer Konfigurationen möglich, solange für jede Konfigurationsdatei dieselbe login_url- und accounts_endpoint-URL verwendet wird.

Hinweis: Der Parameter wird ab Chrome 132 unterstützt.
login_url empfohlen, erfordert accounts_endpoint Die URL der Anmeldeseite, über die sich der Nutzer beim IdP anmelden kann. So ist die Unterstützung mehrerer Konfigurationen möglich, solange in jeder Konfigurationsdatei dieselbe login_url und accounts_endpoint verwendet wird.

Hinweis: Der Parameter wird ab Chrome 132 unterstützt.

Wenn die IdP-Endpunkte beispielsweise unter https://accounts.idp.example/ bereitgestellt werden, müssen sie eine .well-known-Datei unter https://idp.example/.well-known/web-identity sowie eine IdP-Konfigurationsdatei bereitstellen. Hier ein Beispiel für einen bekannten Dateiinhalt:

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

IdPs können mehrere Konfigurationsdateien für einen IdP aufnehmen, indem in der bekannten Datei accounts_endpoint und login_url angegeben werden.
Diese Funktion kann in folgenden Fällen nützlich sein:

  • Ein Identitätsanbieter muss mehrere unterschiedliche Test- und Produktionskonfigurationen unterstützen.
  • Ein Identitätsanbieter muss unterschiedliche Konfigurationen pro Region unterstützen (z. B. eu-idp.example und us-idp.example).

Um mehrere Konfigurationen zu unterstützen (z. B. um zwischen Test- und Produktionsumgebung zu unterscheiden), muss der Identitätsanbieter accounts_endpoint und login_url angeben:

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

IdP-Konfigurationsdatei und Endpoints erstellen

Die IdP-Konfigurationsdatei enthält eine Liste der erforderlichen Endpunkte für den Browser. IdPs müssen eine oder mehrere Konfigurationsdateien sowie die erforderlichen Endpunkte und URLs hosten. Alle JSON-Antworten müssen mit dem Inhaltstyp application/json bereitgestellt werden.

Die URL der Konfigurationsdatei wird anhand der Werte bestimmt, die für den navigator.credentials.get()-Aufruf angegeben werden, der auf einem RP ausgeführt wird.

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

Der RP gibt die URL der Konfigurationsdatei an den FedCM API-Aufruf weiter, damit sich der Nutzer anmelden kann:

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

Der Browser ruft die Konfigurationsdatei mit einer GET-Anfrage ohne den Origin- oder Referer-Header ab. Die Anfrage enthält keine Cookies und folgt keinen Weiterleitungen. So kann die IdP nicht herausfinden, wer die Anfrage gestellt hat und welcher RP eine Verbindung herstellen möchte. Beispiel:

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

Der Identitätsanbieter muss einen Konfigurationsendpunkt implementieren, der mit einer JSON-Antwort antwortet. Das JSON-Objekt enthält die folgenden Eigenschaften:

Attribut Beschreibung
accounts_endpoint (erforderlich) URL für den Kontenendpunkt.
accounts.include (optional) Benutzerdefinierter String für das Kontolabel, der angibt, welche Konten bei Verwendung dieser Konfigurationsdatei zurückgegeben werden sollen, z. B. "accounts": {"include": "developer"}.
Ein IdP kann benutzerdefinierte Kontolabels so implementieren:
  • Erstellen Sie eine Konfigurationsdatei, die mit bestimmten Labels verknüpft ist (mit diesem accounts.include-Parameter).
  • Geben Sie Labels im Endpunkt „accounts“ an.

Ein IdP implementiert beispielsweise die "https://idp.example/developer-config.json" Konfigurationsdatei mit "accounts": {"include": "developer"}. Der IdP kennzeichnet einige Konten auch mit dem Label "developer", indem er den Parameter labels im Endpunkt „accounts“ verwendet. Wenn ein RP navigator.credentials.get() mit der Konfigurationsdatei "https://idp.example/developer-config.json" aufruft, werden nur Konten mit dem Label "developer" zurückgegeben.

Hinweis: Benutzerdefinierte Kontolabels werden ab Chrome 132 unterstützt.
client_metadata_endpoint (optional) URL für den Endpunkt für Clientmetadaten.
id_assertion_endpoint (erforderlich) URL für den Endpunkt für Identitätsbestätigungen.
disconnect (optional) URL für den Disconnect-Endpunkt.
login_url (erforderlich) Die URL der Anmeldeseite, über die sich der Nutzer beim IdP anmelden kann.
branding (optional) Objekt mit verschiedenen Branding-Optionen.
branding.background_color (optional) Brandingoption, mit der die Hintergrundfarbe der Schaltfläche „Als… fortfahren“ festgelegt wird. Verwenden Sie die entsprechende CSS-Syntax: hex-color, hsl(), rgb() oder named-color.
branding.color (optional) Brandingoption, mit der die Textfarbe der Schaltfläche „Als… fortfahren“ festgelegt wird. Verwenden Sie die entsprechende CSS-Syntax: hex-color, hsl(), rgb() oder named-color.
branding.icons (optional) Array von Symbolobjekten. Diese Symbole werden im Anmeldedialogfeld angezeigt. Das Symbolobjekt hat zwei Parameter:
  • url (erforderlich): URL des Symbolbilds. SVG-Bilder werden nicht unterstützt.
  • size (optional): Symbolabmessungen, die von der Anwendung als quadratisch und mit einer einzigen Auflösung angenommen werden. Diese Zahl muss im passiven Modus mindestens 25 px und im aktiven Modus mindestens 40 px betragen.
modes Objekt mit Spezifikationen dazu, wie die FedCM-Benutzeroberfläche in verschiedenen Modi angezeigt wird:
  • active
  • passive
modes.active Objekt mit Eigenschaften, mit denen sich das FedCM-Verhalten in einem bestimmten Modus anpassen lässt. Sowohl modes.active als auch modes.passive können den folgenden Parameter enthalten:
  • supports_use_other_account: Boolescher Wert, der angibt, ob sich der Nutzer mit einem anderen Konto als dem anmelden kann, mit dem er derzeit angemeldet ist (falls der IdP mehrere Konten unterstützt).

Hinweis: Die Funktion „Anderes Konto verwenden“ und der aktive Modus werden ab Chrome 132 unterstützt.
modes.passive

Hier ist ein Beispiel für den Antworttext des Identitätsanbieters:

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

Sobald der Browser die Konfigurationsdatei abgerufen hat, sendet er nachfolgende Anfragen an die IdP-Endpunkte:

IdP-Endpunkte
IdP-Endpunkte

Anderes Konto verwenden

Nutzer können zu einem anderen Konto wechseln, als mit dem sie derzeit angemeldet sind, wenn der Identitätsanbieter mehrere Konten unterstützt oder das vorhandene Konto ersetzt.

Damit der Nutzer andere Konten auswählen kann, muss der IdP diese Funktion in der Konfigurationsdatei angeben:

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

Endpunkt für Konten

Der Endpunkt „accounts“ des Identitätsanbieters gibt eine Liste der Konten zurück, in denen der Nutzer beim Identitätsanbieter angemeldet ist. Wenn der Identitätsanbieter mehrere Konten unterstützt, werden über diesen Endpunkt alle angemeldeten Konten zurückgegeben.

Der Browser sendet eine GET-Anfrage mit Cookies mit SameSite=None, aber ohne client_id-Parameter, Origin-Header oder Referer-Header. So kann der IdP nicht herausfinden, bei welchem RP sich der Nutzer anmelden möchte. Beispiel:

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

Nach Erhalt der Anfrage sollte der Server Folgendes tun:

  1. Prüfe, ob die Anfrage einen Sec-Fetch-Dest: webidentity-HTTP-Header enthält.
  2. Ordnen Sie die Sitzungscookies den IDs der bereits angemeldeten Konten zu.
  3. Antworten Sie mit der Liste der Konten.

Der Browser erwartet eine JSON-Antwort, die eine accounts-Eigenschaft mit einem Array von Kontoinformationen mit den folgenden Eigenschaften enthält:

Attribut Beschreibung
id (erforderlich) Die eindeutige ID des Nutzers.
name (erforderlich) Vorname und Nachname des Nutzers.
email (erforderlich) E-Mail-Adresse des Nutzers
given_name (optional) Vorname des Nutzers.
picture (optional) URL des Avatarbilds des Nutzers.
approved_clients (optional) Ein Array von RP-Client-IDs, mit denen sich der Nutzer registriert hat.
login_hints (optional) Ein Array aller möglichen Filtertypen, die der IdP zur Angabe eines Kontos unterstützt. Der RP kann navigator.credentials.get() mit der Property loginHint aufrufen, um das angegebene Konto selektiv anzuzeigen.
domain_hints (optional) Ein Array aller Domains, die dem Konto zugeordnet sind. Der RP kann navigator.credentials.get() mit einer domainHint-Property aufrufen, um die Konten zu filtern.
labels (optional) Array von Strings mit benutzerdefinierten Kontolabels, die mit einem Konto verknüpft sind.
Ein IdP kann benutzerdefinierte Kontolabels so implementieren:
  • Geben Sie Kontolabels im Endpunkt „accounts“ an (mithilfe des Parameters labels).
  • Erstellen Sie für jedes Label eine Konfigurationsdatei.

Ein IdP implementiert beispielsweise die https://idp.example/developer-config.json Konfigurationsdatei mit "accounts": {"include": "developer"}. Der IdP kennzeichnet einige Konten auch mit dem Label "developer", indem er den Parameter labels im Kontoendpunkt verwendet. Wenn ein RP navigator.credentials.get() mit der Konfigurationsdatei https://idp.example/developer-config.json aufruft, werden nur Konten mit dem Label "developer" zurückgegeben.

Benutzerdefinierte Kontolabels unterscheiden sich von Anmelde- und Domainhinweisen dadurch, dass sie vollständig vom IdP-Server verwaltet werden und der RP nur die zu verwendende Konfigurationsdatei angibt.

Hinweis: Benutzerdefinierte Kontolabels werden ab Chrome 132 unterstützt.

Beispiel für einen Antworttext:

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

Wenn der Nutzer nicht angemeldet ist, antworte mit HTTP 401 (Nicht autorisiert).

Die zurückgegebene Kontoliste wird vom Browser verwendet und ist für den RP nicht verfügbar.

Endpunkt für Identitätsbestätigung

Der Endpunkt für Identitätsbestätigungen des IdP gibt eine Bestätigung für den angemeldeten Nutzer zurück. Wenn sich der Nutzer über einen navigator.credentials.get()-Aufruf auf einer RP-Website anmeldet, sendet der Browser eine POST-Anfrage mit Cookies mit SameSite=None und einem Inhaltstyp von application/x-www-form-urlencoded an diesen Endpunkt mit den folgenden Informationen:

Attribut Beschreibung
client_id (erforderlich) Die Client-ID des RP.
account_id (erforderlich) Die eindeutige ID des Nutzers, der sich anmeldet.
disclosure_text_shown Das Ergebnis ist ein String mit "true" oder "false" (kein boolescher Wert). In folgenden Fällen wird das Ergebnis "false" zurückgegeben:
  • Wenn der Hinweis nicht angezeigt wurde, weil die Client-ID des RP in der approved_clients-Eigenschaftsliste der Antwort vom Endpunkt „accounts“ enthalten war.
  • Wenn der Hinweis nicht angezeigt wurde, weil der Browser in der Vergangenheit eine Registrierung ohne approved_clients festgestellt hat.
  • Wenn der Parameter fields eines oder mehrere der drei Felder („name“, „email“ und „picture“) nicht enthält, z. B. fields=[ ] oder fields=['name', 'picture']. Dies ist für die Abwärtskompatibilität mit älteren IdP-Implementierungen erforderlich, bei denen ein Offenlegungsstring immer alle drei Felder enthalten muss.
is_auto_selected Wenn die automatische Reautorisierung auf dem RP ausgeführt wird, entspricht is_auto_selected "true". Andernfalls "false". Dies ist hilfreich, um mehr sicherheitsbezogene Funktionen zu unterstützen. Einige Nutzer bevorzugen beispielsweise eine höhere Sicherheitsstufe, bei der eine explizite Nutzermitwirkung bei der Authentifizierung erforderlich ist. Wenn ein IdP eine Tokenanfrage ohne diese Vermittlung erhält, kann er die Anfrage anders verarbeiten. Gib beispielsweise einen Fehlercode zurück, damit der RP die FedCM API noch einmal mit mediation: required aufrufen kann.
fields (optional) Array von Strings, das die Nutzerinformationen („name“, „email“, „picture“) angibt, die der RP vom IdP benötigt.
Der Browser sendet fields, disclosure_text_shown und disclosure_shown_for mit den angegebenen Feldern in der POST-Anfrage, wie im folgenden Beispiel.

Hinweis: Der Parameter „Felder“ wird ab Chrome 132 unterstützt.
params (optional) Ein gültiges JSON-Objekt, mit dem zusätzliche benutzerdefinierte Schlüssel/Wert-Parameter angegeben werden können, z. B.:
  • scope: Ein Stringwert mit zusätzlichen Berechtigungen, die der RP anfordern muss, z. B. "drive.readonly calendar.readonly"
  • nonce: Ein zufälliger String, der vom RP bereitgestellt wird, um sicherzustellen, dass die Antwort für diese bestimmte Anfrage ausgestellt wird. Verhindert Replay-Angriffe.
  • Andere benutzerdefinierte Schlüssel/Wert-Paar-Parameter
Wenn der Browser eine POST-Anfrage sendet, wird der params-Wert in JSON serialisiert und dann prozentcodiert.

Hinweis: Die Parameters API wird von Chrome 132 und höher unterstützt.

Beispiel für einen HTTP-Header:

  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

Nach Erhalt der Anfrage sollte der Server Folgendes tun:

  1. Antworten Sie mit CORS (Cross-Origin Resource Sharing) auf die Anfrage.
  2. Prüfe, ob die Anfrage einen Sec-Fetch-Dest: webidentity-HTTP-Header enthält.
  3. Vergleiche den Origin-Header mit dem RP-Ursprung, der durch den client_id bestimmt wird. Lehnen Sie sie ab, wenn sie nicht übereinstimmen.
  4. Vergleiche account_id mit der ID des bereits angemeldeten Kontos. Lehnen Sie sie ab, wenn sie nicht übereinstimmen.
  5. Mit einem Token antworten Wenn die Anfrage abgelehnt wird, antworte mit einer Fehlerantwort.

Der Identitätsanbieter kann festlegen, wie das Token ausgestellt wird. Im Allgemeinen wird es mit Informationen wie der Konto-ID, der Client-ID, dem Ausstellerursprung und dem Nonce signiert, damit der RP die Echtheit des Tokens überprüfen kann.

Der Browser erwartet eine JSON-Antwort mit der folgenden Eigenschaft:

Attribut Beschreibung
token Ein Token ist ein String, der Ansprüche zur Authentifizierung enthält.
continue_on Weiterleitungs-URL, die eine mehrstufige Anmeldeabfolge ermöglicht.

Das zurückgegebene Token wird vom Browser an den RP übergeben, damit dieser die Authentifizierung validieren kann.

  {
    // IdP can respond with a token to authenticate the user
    "token": "***********"
  }

Funktion „Weiter“

Der IdP kann im Endpunkt für die ID-Bestätigung eine Weiterleitungs-URL angeben, um einen mehrstufigen Anmeldevorgang zu ermöglichen. Das ist nützlich, wenn der Identitätsanbieter zusätzliche Informationen oder Berechtigungen anfordern muss, z. B. in folgenden Fällen:

  • Berechtigung zum Zugriff auf die serverseitigen Ressourcen des Nutzers.
  • Bestätigung, dass die Kontaktdaten aktuell sind
  • Jugendschutzeinstellungen.

Der Endpunkt für die Bestätigung der Identität kann eine continue_on-Property zurückgeben, die einen absoluten oder relativen Pfad zum Endpunkt für die Bestätigung der Identität enthält.

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

Wenn die Antwort den Parameter continue_on enthält, wird ein neues Pop-up-Fenster geöffnet und der Nutzer wird zum angegebenen Pfad weitergeleitet. Nach der Nutzerinteraktion mit der Seite continue_on sollte der IdP IdentityProvider.resolve() mit dem Token als Argument aufrufen, damit das Versprechen aus dem ursprünglichen navigator.credentials.get()-Aufruf aufgelöst werden kann:

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

Der Browser schließt dann automatisch das Pop-up und gibt das Token an den API-Caller zurück. Ein einmaliger IdentityProvider.resolve()-Aufruf ist die einzige Möglichkeit, wie das übergeordnete Fenster (RP) und das Pop-up-Fenster (IdP) miteinander kommunizieren können.
Wenn der Nutzer die Anfrage ablehnt, kann der IdP das Fenster schließen, indem er IdentityProvider.close() aufruft.

  IdentityProvider.close();

Die Continuation API erfordert eine explizite Nutzerinteraktion (Klicks), um zu funktionieren. So funktioniert die Continuation API mit verschiedenen Vermittlungsmodi:

  • Im passiven Modus:
    • mediation: 'optional' (Standardeinstellung): Die Continuation API funktioniert nur mit einer Nutzergeste, z. B. dem Klicken auf eine Schaltfläche auf der Seite oder auf der FedCM-Benutzeroberfläche. Wenn die automatische Neuauthentifizierung ohne Nutzergeste ausgelöst wird, wird kein Pop-up-Fenster geöffnet und das Versprechen wird abgelehnt.
    • mediation: 'required': Der Nutzer wird immer aufgefordert, zu interagieren, sodass die Continuation API immer funktioniert.
  • Im aktiven Modus:
    • Eine Nutzeraktivierung ist immer erforderlich. Die Continuation API ist kompatibel.

Wenn der Nutzer aus irgendeinem Grund sein Konto im Pop-up geändert hat (z. B. wenn der IdP die Funktion „Anderes Konto verwenden“ anbietet oder bei der Delegierung), kann der resolve-Aufruf ein optionales zweites Argument annehmen, z. B.:

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

Fehlerantwort zurückgeben

id_assertion_endpoint kann auch eine „error“-Antwort zurückgeben, die zwei optionale Felder enthält:

  • code: Der IdP kann einen der bekannten Fehler aus der in OAuth 2.0 angegebenen Fehlerliste (invalid_request, unauthorized_client, access_denied, server_error und temporarily_unavailable) auswählen oder einen beliebigen String verwenden. In diesem Fall rendert Chrome die Fehler-UI mit einer generischen Fehlermeldung und übergibt den Code an den RP.
  • url: Hier wird eine lesbare Webseite mit Informationen zum Fehler angegeben, um Nutzern zusätzliche Informationen zum Fehler zur Verfügung zu stellen. Dieses Feld ist für Nutzer nützlich, da Browser keine umfassenden Fehlermeldungen in einer integrierten Benutzeroberfläche anzeigen können. Zum Beispiel: Links zu den nächsten Schritten oder Kontaktdaten des Kundenservice. Wenn ein Nutzer mehr über die Fehlerdetails und die Behebung erfahren möchte, kann er die bereitgestellte Seite über die Browser-Benutzeroberfläche aufrufen. Die URL muss der Website des Identitätsanbieters configURL entsprechen.
  // id_assertion_endpoint response
  {
    "error" : {
      "code": "access_denied",
      "url" : "https://idp.example/error?type=access_denied"
    }
  }

Benutzerdefinierte Kontolabels

Mit Benutzerdefinierte Kontolabels kann der Identitätsanbieter Nutzerkonten mit Labels versehen. Der RP kann dann festlegen, dass nur Konten mit bestimmten Labels abgerufen werden sollen, indem er die configURL für das jeweilige Label angibt. Das kann hilfreich sein, wenn ein RP Konten nach bestimmten Kriterien herausfiltern muss, z. B. um nur rollenspezifische Konten wie "developer" oder "hr" anzuzeigen.

Ähnliche Filter sind mit den Funktionen Domainhinweis und Anmeldehinweis möglich. Geben Sie sie dazu im navigator.credentials.get()-Aufruf an. Mit benutzerdefinierten Kontolabels können Nutzer jedoch durch Angabe der Konfigurationsdatei gefiltert werden. Das ist besonders nützlich, wenn mehrere Konfigurations-URLs verwendet werden. Benutzerdefinierte Kontolabels unterscheiden sich auch dadurch, dass sie vom IdP-Server und nicht vom RP bereitgestellt werden, z. B. Anmelde- oder Domainhinweise.

Angenommen, ein Identitätsanbieter möchte zwischen "developer"- und "hr"-Konten unterscheiden. Dazu muss der IdP zwei configURLs für "developer" und "hr" unterstützen:

  • Die Entwicklerkonfigurationsdatei https://idp.example/developer/fedcm.json hat das Label "developer" und die Unternehmenskonfigurationsdatei https://idp.example/hr/fedcm.json das Label "hr":
  // 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"
    }
  }
  • Bei einer solchen Konfiguration sollte die well-known-Datei accounts_endpoint und login_url enthalten, um mehrere configURLs zuzulassen:
  {
    "provider_urls": [ "https://idp.example/fedcm.json" ],
    "accounts_endpoint": "https://idp.example/accounts",
    "login_url": "https://idp.example/login"
  }
  • Der gemeinsame Endpunkt für Konten des Identitätsanbieters (in diesem Beispiel https://idp.example/accounts) gibt eine Liste von Konten zurück, die für jedes Konto ein labels-Attribut mit zugewiesenen Labels in einem Array enthält:
  {
  "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"]
    }]
  }

Wenn ein RP "hr"-Nutzern die Anmeldung erlauben möchte, kann er die configURL https://idp.example/hr/fedcm.json im navigator.credentials.get()-Aufruf angeben:

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

Daher ist für die Anmeldung des Nutzers nur die Konto-ID 4567 verfügbar. Die Konto-ID 123 wird vom Browser automatisch ausgeblendet, damit dem Nutzer kein Konto zugewiesen wird, das vom IdP auf dieser Website nicht unterstützt wird.

  • Labels sind Strings. Wenn das Array labels oder das Feld include einen anderen Wert als einen String enthält, wird es ignoriert.
  • Wenn in der configURL keine Labels angegeben sind, werden alle Konten in der FedCM-Kontoauswahl angezeigt.
  • Wenn für ein Konto keine Labels angegeben sind, wird es nur in der Kontoauswahl angezeigt, wenn auch für configURL kein Label angegeben ist.
  • Wenn im passiven Modus kein Konto mit dem angeforderten Label übereinstimmt (ähnlich wie bei der Funktion „Domainhinweis“), wird im FedCM-Dialogfeld eine Anmeldeaufforderung angezeigt, über die sich der Nutzer in einem IdP-Konto anmelden kann. Im aktiven Modus wird das Pop-up-Fenster für die Anmeldung direkt geöffnet.

Endpunkt trennen

Durch das Aufrufen von IdentityCredential.disconnect() sendet der Browser eine ursprungsübergreifende POST-Anfrage mit Cookies mit SameSite=None und dem Inhaltstyp application/x-www-form-urlencoded an diesen Disconnect-Endpunkt mit den folgenden Informationen:

Attribut Beschreibung
account_hint Ein Hinweis für das IdP-Konto.
client_id Die Client-ID des 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

Nach Erhalt der Anfrage sollte der Server Folgendes tun:

  1. Antworten Sie mit CORS (Cross-Origin Resource Sharing) auf die Anfrage.
  2. Prüfe, ob die Anfrage einen Sec-Fetch-Dest: webidentity-HTTP-Header enthält.
  3. Vergleiche den Origin-Header mit dem RP-Ursprung, der durch den client_id bestimmt wird. Lehnen Sie sie ab, wenn sie nicht übereinstimmen.
  4. Vergleiche account_hint mit den IDs der bereits angemeldeten Konten.
  5. Trennen Sie die Verknüpfung des Nutzerkontos mit dem RP.
  6. Antworte dem Browser mit den Informationen zum identifizierten Nutzerkonto im JSON-Format.

Eine Beispiel-JSON-Nutzlast für eine Antwort sieht so aus:

  {
    "account_id": "account456"
  }

Wenn der IdP stattdessen möchte, dass der Browser die Verbindung zu allen Konten aufhebt, die mit dem RP verknüpft sind, muss er einen String übergeben, der mit keiner Konto-ID übereinstimmt, z. B. "*".

Client-Metadatenendpunkt

Der Client-Metadatenendpunkt der IdP gibt die Metadaten der vertrauenden Partei zurück, z. B. die Datenschutzerklärung, die Nutzungsbedingungen und Logosymbole der vertrauenden Partei. RPs sollten dem Identitätsanbieter im Voraus Links zu ihrer Datenschutzerklärung und ihren Nutzungsbedingungen zur Verfügung stellen. Diese Links werden im Anmeldedialogfeld angezeigt, wenn sich der Nutzer noch nicht beim RP beim IdP registriert hat.

Der Browser sendet eine GET-Anfrage mit der client_id navigator.credentials.get ohne Cookies. Beispiel:

  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

Nach Erhalt der Anfrage sollte der Server Folgendes tun:

  1. Ermitteln Sie den RP für die client_id.
  2. Antworten Sie mit den Client-Metadaten.

Zu den Eigenschaften für den Client-Metadatenendpunkt gehören:

Attribut Beschreibung
privacy_policy_url (optional) URL der Datenschutzerklärung des Rechtssubjekts.
terms_of_service_url (optional) URL der Nutzungsbedingungen des Resellers.
icons (optional) Array von Objekten, z. B. [{ "url": "https://rp.example/rp-icon.ico", "size": 40}]

Der Browser erwartet vom Endpunkt eine JSON-Antwort:

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

Die zurückgegebenen Clientmetadaten werden vom Browser verwendet und sind für den RP nicht verfügbar.

Anmelde-URL

Über diesen Endpunkt kann sich der Nutzer beim IdP anmelden.

Mit der Login Status API muss der Identitätsanbieter den Anmeldestatus des Nutzers an den Browser weitergeben. Der Status kann jedoch nicht mehr aktuell sein, z. B. wenn die Sitzung abläuft. In einem solchen Szenario kann der Browser den Nutzer dynamisch über die Anmeldeseiten-URL in der login_url der IdP-Konfigurationsdatei beim IdP anmelden.

Im FedCM-Dialogfeld wird eine Meldung angezeigt, in der eine Anmeldung vorgeschlagen wird (siehe Abbildung unten).

A
Ein FedCM-Dialogfeld, in dem zur Anmeldung beim IdP aufgefordert wird.

Wenn der Nutzer auf die Schaltfläche Weiter klickt, öffnet der Browser ein Pop-up-Fenster für die Anmeldeseite des Identitätsanbieters.

Beispiel für ein FedCM-Dialogfeld
Beispiel für ein Dialogfeld, das nach dem Klicken auf die Schaltfläche „Über den Identitätsanbieter anmelden“ angezeigt wird.

Das Dialogfeld ist ein normales Browserfenster mit eigenen Cookies. Was im Dialogfeld passiert, liegt im Ermessen des Identitätsanbieters. Es sind keine Fenster-Handles verfügbar, um eine plattformübergreifende Kommunikationsanfrage an die RP-Seite zu senden. Nachdem sich der Nutzer angemeldet hat, sollte der Identitätsanbieter Folgendes tun:

  • Sende den Set-Login: logged-in-Header oder rufe die navigator.login.setStatus("logged-in") API auf, um den Browser darüber zu informieren, dass der Nutzer angemeldet ist.
  • Drücken Sie IdentityProvider.close(), um das Dialogfeld zu schließen.
Ein Nutzer meldet sich bei einem RP an, nachdem er sich mit FedCM beim IdP angemeldet hat.

Browser über den Anmeldestatus des Nutzers informieren

Die Login Status API ist ein Mechanismus, bei dem eine Website, insbesondere ein Identitätsanbieter, den Browser über den Anmeldestatus des Nutzers beim Identitätsanbieter informiert. Mit dieser API kann der Browser unnötige Anfragen an den Identitätsanbieter reduzieren und potenzielle Timing-Angriffe abwehren.

Identitätsanbieter können den Anmeldestatus des Nutzers an den Browser senden, indem sie einen HTTP-Header senden oder eine JavaScript API aufrufen, wenn der Nutzer beim Identitätsanbieter angemeldet ist oder von allen seinen Identitätsanbieterkonten abgemeldet ist. Für jeden IdP (identifiziert durch seine Konfigurations-URL) speichert der Browser eine Drei-Zustands-Variable, die den Anmeldestatus mit den folgenden möglichen Werten darstellt:

  • logged-in
  • logged-out
  • unknown (Standard)
Anmeldestatus Beschreibung
logged-in Wenn der Anmeldestatus des Nutzers auf logged-in gesetzt ist, sendet die RP, die FedCM aufruft, Anfragen an den Kontoendpunkt des Identitätsanbieters und zeigt dem Nutzer im FedCM-Dialogfeld verfügbare Konten an.
logged-out Wenn der Anmeldestatus des Nutzers logged-out ist, schlägt der Aufruf von FedCM stillschweigend fehl, ohne dass eine Anfrage an den Kontoendpunkt des IdP gesendet wird.
unknown (Standard) Der unknown-Status wird festgelegt, bevor der Identitätsanbieter ein Signal über die Login Status API sendet. Wenn der Status unknown ist, sendet der Browser eine Anfrage an den Kontenendpunkt des Identitätsanbieters und aktualisiert den Status anhand der Antwort vom Kontenendpunkt.

Um anzuzeigen, dass der Nutzer angemeldet ist, senden Sie einen Set-Login: logged-in-HTTP-Header in einer Navigation auf oberster Ebene oder eine Anfrage für eine Subressource auf derselben Website am IdP-Ursprung:

  Set-Login: logged-in

Alternativ können Sie die JavaScript-Methode navigator.login.setStatus('logged-in') vom IdP-Ursprung in einer Navigation auf oberster Ebene aufrufen:

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

Der Anmeldestatus des Nutzers wird auf logged-in gesetzt.

Um anzuzeigen, dass der Nutzer von allen seinen Konten abgemeldet ist, senden Sie einen Set-Login: logged-out-HTTP-Header in einer Navigation auf oberster Ebene oder eine Subressourcen-Anfrage auf derselben Website am IdP-Ursprung:

  Set-Login: logged-out

Alternativ können Sie die JavaScript API navigator.login.setStatus('logged-out') über den IdP-Ursprung in einer Navigation der obersten Ebene aufrufen:

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

Der Anmeldestatus des Nutzers wird auf logged-out gesetzt.

Der Status unknown wird festgelegt, bevor der Identitätsanbieter ein Signal über die Login Status API sendet. Der Browser sendet eine Anfrage an den Kontoendpunkt des Identitätsanbieters und aktualisiert den Status basierend auf der Antwort vom Kontoendpunkt:

  • Wenn der Endpunkt eine Liste aktiver Konten zurückgibt, aktualisiere den Status zu logged-in und öffne das FedCM-Dialogfeld, um diese Konten anzuzeigen.
  • Wenn der Endpunkt keine Konten zurückgibt, aktualisiere den Status auf logged-out und scheitere den FedCM-Aufruf.

Nutzer über einen dynamischen Anmeldevorgang anmelden

Auch wenn der Identitätsanbieter den Anmeldestatus des Nutzers ständig an den Browser weitergibt, kann es zu einer Synchronisierungsverzögerung kommen, z. B. wenn die Sitzung abläuft. Der Browser versucht, eine Anfrage mit Anmeldedaten an den Endpunkt „accounts“ zu senden, wenn der Anmeldestatus logged-in ist. Der Server gibt jedoch keine Konten zurück, da die Sitzung nicht mehr verfügbar ist. In einem solchen Szenario kann der Browser den Nutzer dynamisch über ein Pop-up-Fenster beim IdP anmelden.

Nächste Schritte

Implementiere FedCM für deine RPs und verteile das JavaScript SDK. Sie müssen keine Richtlinien mehr selbst implementieren, sodass sie immer auf dem neuesten Stand sind.
Hier erfahren Sie, wie Sie Ihre Umgebung einrichten und Ihre Implementierung debuggen.