Ab Chrome 126 können Entwickler einen Ursprungstest für eine Reihe von FedCM-Funktionen (FedCM) für Desktop-Computer ausführen, die einige Anwendungsfälle der Autorisierung ermöglichen. Das Bundle besteht aus der Continuation API und der Parameters API. Diese ermöglichen einen OAuth-Autorisierungsablauf ähnlich wie ein Berechtigungsdialogfeld, das vom Identitätsanbieter (IdP) bereitgestellt wird. Das Bundle enthält auch andere Änderungen wie die Fields API, mehrere configURLs und benutzerdefinierte Kontolabels. Ab Chrome 126 führen wir auch einen Ursprungstest für die Storage Access API (SAA) ein, bei dem SAA-Anfragen automatisch genehmigt werden, wenn sich der Nutzer in der Vergangenheit erfolgreich mit FedCM angemeldet hat.
Ursprungstest: FedCM Continuation API-Bundle
Das FedCM Continuation API-Bundle besteht aus mehreren FedCM-Erweiterungen:
Continuation API
Du kannst dir eine Demo der API auf Glitch ansehen.
Mit der Continuation API kann der ID-Assertion-Endpunkt des IdP optional eine URL zurückgeben, die FedCM rendert, damit der Nutzer einen mehrstufigen Anmeldevorgang fortsetzen kann. So kann der IdP den Nutzer bitten, der vertrauenswürdigen Partei (RP) Berechtigungen zu gewähren, die über das hinausgehen, was in der vorhandenen FedCM-Benutzeroberfläche möglich ist, z. B. Zugriff auf die serverseitigen Ressourcen des Nutzers.
Normalerweise gibt der ID-Assertion-Endpunkt ein Token zurück, das für die Authentifizierung erforderlich ist.
{
"token": "***********"
}
Mit der Continuation API kann der ID-Assertion-Endpunkt jedoch ein continue_on
-Attribut zurückgeben, das einen absoluten Pfad oder einen relativen Pfad zum ID-Assertion-Endpunkt 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 pop-up window:
"continue_on": "/oauth/authorize?scope=..."
}
Sobald der Browser die continue_on
-Antwort erhält, wird ein neues Pop-up-Fenster geöffnet, in dem der Nutzer zum angegebenen Pfad weitergeleitet wird.
Nachdem der Nutzer mit der Seite interagiert hat, z. B. eine weitere Berechtigung zur Weitergabe zusätzlicher Informationen an die RP erteilt hat, kann die IdP-Seite IdentityProvider.resolve()
aufrufen, um den ursprünglichen navigator.credentials.get()
-Aufruf aufzulösen und ein Token als Argument zurückzugeben.
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 automatisch und gibt das Token an den API-Caller zurück.
Wenn der Nutzer die Anfrage ablehnt, können Sie das Fenster durch Aufrufen von IdentityProvider.close()
schließen.
IdentityProvider.close();
Wenn der Nutzer aus irgendeinem Grund sein Konto im Pop-up geändert hat (z. B. bietet der IdP eine Funktion zum Wechseln des Nutzers an oder in Delegierungsfällen), verwendet der Auflösungsaufruf ein optionales zweites Argument, das in etwa Folgendes zulässt:
IdentityProvider.resolve(token, {accountId: '1234');
Parameter-API
Mit der Parameters API kann der RP dem Endpunkt für die ID-Bestätigung zusätzliche Parameter zur Verfügung stellen. Mit der Parameters API können RPs zusätzliche Parameter an den IdP übergeben, um Berechtigungen für Ressourcen über die grundlegende Anmeldung hinaus anzufordern. Der Nutzer autorisiert diese Berechtigungen über einen IdP-gesteuerten UX-Ablauf, der über die Continuation API gestartet wird.
Wenn Sie die API verwenden möchten, fügen Sie der params
-Eigenschaft als Objekt im navigator.credentials.get()
-Aufruf Parameter hinzu.
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',
}
},
}
});
Die Attributnamen im params
-Objekt werden mit param_
vorangestellt. Im obigen Beispiel enthält das Attribut „params“ IDP_SPECIFIC_PARAM
als '1'
, foo
als 'BAR'
, ETC
als 'MOAR'
und scope
als 'calendar.readonly photos.write'
.
Dies wird im HTTP-Text der Anfrage in param_IDP_SPECIFIC_PARAM=1¶m_foo=BAR¶m_ETC=MOAR¶m_scope=calendar.readonly%20photos.write
umgewandelt:
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¶m_IDP_SPECIFIC_PARAM=1¶m_foo=BAR¶m_ETC=MOAR¶m_scope=calendar.readonly%20photos.write
Berechtigungen dynamisch abrufen
Im Allgemeinen ist es für Nutzer am hilfreichsten, Berechtigungen dann anzufordern, wenn sie benötigt werden, und nicht, wenn der Entwickler der Meinung ist, dass sie sich am einfachsten implementieren lassen. Es ist beispielsweise besser, um die Berechtigung zum Zugriff auf eine Kamera zu bitten, wenn der Nutzer ein Foto aufnehmen möchte, als um die Berechtigung zu bitten, sobald der Nutzer die Website aufruft. Dasselbe gilt für Serverressourcen. Fordern Sie Berechtigungen nur dann an, wenn sie für den Nutzer benötigt werden. Dies wird als „dynamische Autorisierung“ bezeichnet.
Um die Autorisierung dynamisch mit FedCM anzufordern, kann der IdP:
- Rufen Sie
navigator.credentials.get()
mit den erforderlichen Parametern auf, die der IdP verstehen kann, z. B.scope
. - Der ID-Bestätigungsendpunkt bestätigt, dass der Nutzer bereits angemeldet ist, und antwortet mit einer
continue_on
-URL. - Der Browser öffnet ein Pop-up-Fenster mit der Berechtigungsseite des Identitätsanbieters, in dem um eine zusätzliche Berechtigung gebeten wird, die den angeforderten Bereichen entspricht.
- Sobald die Autorisierung über
IdentityProvider.resolve()
durch den IdP erfolgt ist, wird das Fenster geschlossen und der ursprünglichenavigator.credentials.get()
-Aufruf des RP erhält ein relevantes Token oder einen Autorisierungscode, damit der RP es gegen ein gültiges Zugriffstoken austauschen kann.
Fields API
Mit der Fields API kann der RP Kontoattribute deklarieren, die vom IdP angefordert werden sollen, damit der Browser eine ordnungsgemäße Offenlegungs-UI im FedCM-Dialogfeld rendern kann. Der IdP ist dafür verantwortlich, die angeforderten Felder in das zurückgegebene Token aufzunehmen. Stellen Sie sich vor, Sie fordern ein „Basisprofil“ in OpenID Connect an, anstatt „Bereiche“ in OAuth.
Wenn Sie die Fields API verwenden möchten, fügen Sie dem Attribut fields
im navigator.credentials.get()
-Aufruf Parameter als Array hinzu. Die Felder können vorerst 'name'
, 'email'
und 'picture'
enthalten, lassen sich aber für später um weitere Werte erweitern.
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 den Endpunkt für die ID-Bestätigung enthält den vom RP angegebenen Parameter fields
. Der Parameter disclosure_text_shown
ist auf true
festgelegt, wenn es sich nicht um einen wiederkehrenden Nutzer handelt. Die Felder, die der Browser dem Nutzer in einem disclosure_shown_for
-Parameter offengelegt hat, sind ebenfalls enthalten:
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 die RP auf zusätzliche Daten des Identitätsanbieters zugreifen muss, z. B. auf einen Kalender, sollte dies wie oben erwähnt mit einem benutzerdefinierten Parameter verwaltet werden. Der IdP gibt eine continue_on
-URL zurück, um die Berechtigung anzufordern.
Wenn fields
ein leeres Array ist, sieht die Anfrage so aus:
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 Benutzeroberfläche für die Offenlegung.
Das ist selbst dann der Fall, wenn die Antwort vom accounts
endpoint (Konten-Endpunkt) keine Client-ID enthält, die mit dem RP in approved_clients
übereinstimmt.
In diesem Fall ist der an den Endpunkt der ID-Assertion gesendete disclosure_text_shown
im HTTP-Text falsch:
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
Mit mehreren configURLs können IdPs mehrere Konfigurationsdateien für einen IdP aufnehmen. Dazu geben sie accounts_endpoint
und login_url
in der bekannten Datei in derselben Datei an wie in den Konfigurationsdateien.
Wenn der .well-known-Datei accounts_endpoint
und login_url
hinzugefügt werden, werden die provider_urls
ignoriert, damit der IdP mehrere Konfigurationsdateien unterstützen kann.
Andernfalls wird provider_urls
weiterhin angewendet, sodass die Funktion abwärtskompatibel ist.
Eine bekannte Datei, die mehrere configURLs unterstützt, kann so 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:
- Rückwärts- und Vorwärtskompatibilität mit vorhandenen bekannten Dateien und der älteren Version von Browsern, die bereits im Einsatz sind.
- Beliebig viele Konfigurationsdateien haben, solange sie alle auf dieselbe
accounts_endpoint
und dieselbelogin_url
verweisen. - Es gibt keine Möglichkeit, der an
accounts_endpoint
gesendeten Abrufanfrage mit Anmeldedaten Entropie hinzuzufügen, da sie auf „.well-known“-Ebene angegeben werden muss.
Die Unterstützung mehrerer configURLs ist optional und die vorhandenen FedCM-Implementierungen können unverändert bleiben.
Benutzerdefinierte Kontolabels
Mit benutzerdefinierten Kontolabels können FedCM-IdPs Konten annotieren, damit RPs sie filtern können, indem sie das Label in einer Konfigurationsdatei angeben. Eine ähnliche Filterung war bereits mit der Domain Hint API und der Login Hint API möglich, indem sie im navigator.credentials.get()
-Aufruf angegeben wurden. Mit den benutzerdefinierten Kontolabels können Nutzer jedoch durch Angabe der Konfigurationsdatei gefiltert werden. Das ist besonders nützlich, wenn mehrere configURLs verwendet werden. Benutzerdefinierte Kontolabels unterscheiden sich außerdem darin, dass sie vom IdP-Server und nicht vom RP bereitgestellt werden, z. B. Anmelde- oder Domainhinweise.
Beispiel
Ein IdP unterstützt zwei configURLs für Nutzer bzw. Unternehmen. Die Konfigurationsdatei für Nutzer hat das Label 'consumer'
und die Konfigurationsdatei für Unternehmen das Label 'enterprise'
.
Bei einer solchen Konfiguration enthält die „well-known“-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 angegeben ist, werden provider_urls
ignoriert. Die RP kann direkt auf die entsprechenden Konfigurationsdateien im navigator.credentials.get()
-Aufruf verweisen.
Die Nutzerkonfigurationsdatei befindet sich unter https://idp.example/fedcm.json
. Sie enthält das Attribut accounts
, das '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 Konfigurationsdatei für Unternehmen befindet sich unter https://idp.example/enterprise/fedcm.json
. Sie enthält das Attribut accounts
, das 'enterprise'
mithilfe von include
angibt.
{
"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"
}
}
Der gemeinsame IdP-Endpunkt für Konten (in diesem Beispiel https://idp.example/accounts
) gibt eine Liste von Konten zurück, die für jedes Konto ein Label-Attribut mit zugewiesenem labels
in einem Array enthält.
Das folgende Beispiel zeigt eine Antwort für einen Nutzer mit zwei Konten. Eine Version ist für Privatnutzer und die 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()
-Aufruf angeben:
let { token } = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
nonce: '234234',
configURL: 'https://idp.example/enterprise/fedcm.json',
},
}
});
Daher ist für die Anmeldung nur die Konto-ID von '4567'
verfügbar. Die Konto-ID von '123'
wird vom Browser lautlos ausgeblendet, damit der Nutzer kein Konto erhält, das vom IdP auf dieser Website nicht unterstützt wird.
Ursprungstest: FedCM als Vertrauenssignal für die Storage Access API
In Chrome 126 wird ein Ursprungstest von FedCM als Vertrauenssignal für die Storage Access API gestartet. Mit dieser Änderung ist eine vorherige Gewährung von Berechtigungen über FedCM ein gültiger Grund für die automatische Genehmigung einer Speicherzugriffsanfrage durch die Storage Access APIs.
Dies ist nützlich, wenn ein eingebetteter iFrame auf personalisierte Ressourcen zugreifen möchte, z. B. wenn idp.example in rp.example eingebettet ist und eine personalisierte Ressource anzeigen muss. Wenn der Browser den Zugriff auf Drittanbieter-Cookies einschränkt, kann der eingebettete idp.example-Frame keine personalisierten Ressourcen anfordern, auch wenn der Nutzer mit FedCM über idp.example in rp.beispiel angemeldet ist. Das liegt daran, dass Anfragen keine Drittanbieter-Cookies enthalten.
Dazu muss idp.beispiel über den auf der Website eingebetteten Iframe eine Berechtigung für den Speicherzugriff erhalten. Diese kann nur über eine Berechtigungsanfrage abgerufen werden.
Wenn FedCM als Vertrauenssignal für die Storage Access API verwendet wird, werden bei den Berechtigungsprüfungen der Storage Access API nicht nur die Berechtigungen akzeptiert, die über einen Prompt für den Speicherzugriff erteilt werden, sondern auch die Berechtigungen, die über einen FedCM-Prompt erteilt werden.
// 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 sich der Nutzer mit FedCM angemeldet hat, wird die Berechtigung automatisch gewährt, solange die FedCM-Authentifizierung aktiv ist. Sobald die Verbindung getrennt ist, wird bei der Berechtigungsanfrage eine Meldung angezeigt.
Am Ursprungstest teilnehmen
Sie können das FedCM Continuation API-Bundle lokal testen. Aktivieren Sie dazu ab Chrome 126 ein Chrome-Flag
chrome://flags#fedcm-authz
. Sie können FedCM auch lokal als Vertrauenssignal für die Storage Access API verwenden. Dazu aktivieren Sie #fedcm-with-storage-access-api
ab Chrome 126.
Diese Funktionen sind auch als Ursprungstests verfügbar. Mit Ursprungstests kannst du neue Funktionen ausprobieren und Feedback zu ihrer Nutzerfreundlichkeit, Praktikabilität und Wirksamkeit geben. Weitere Informationen finden Sie im Hilfeartikel Erste Schritte mit Ursprungstests.
Wenn Sie den Ursprungstest des FedCM Continuation API-Bundles ausprobieren möchten, erstellen Sie zwei Ursprungstesttokens:
- Registrieren Sie sich für den Testzeitraum. Fügen Sie das Token in die IdP-Quelle ein.
- Registrieren Sie sich für den Ursprungstest und klicken Sie das Kästchen für die Drittanbieterabgleiche an. Folgen Sie der Anleitung unter Ursprungstest für Drittanbieter für die RP registrieren, um das Token für die RP einzubetten.
Wenn Sie die Continuation API zusammen mit dem Schaltflächenfluss aktivieren möchten, aktivieren Sie auch den Test für den API-Ursprung des Schaltflächenmodus:
- Registrieren Sie sich als Drittanbieter für den Ursprungstest. Folgen Sie der Anleitung unter Ursprungstest eines Drittanbieters für RP registrieren, um das Token für die RP einzubetten.
So testen Sie FedCM als Vertrauenssignal für den Ursprungstest der Storage Access API:
- Registrieren Sie sich für den Ursprungstest. Betten Sie das Token in den IdP-Ursprung ein.
Der Ursprungstest des Continuation API-Bundles und FedCM als Vertrauenssignal für den Ursprungstest der Storage Access API sind ab Chrome 126 verfügbar.
Ursprungstest eines Drittanbieters für die RP registrieren
- Rufen Sie die Registrierungsseite für den Ursprungstest auf.
- Klicken Sie auf die Schaltfläche Registrieren und füllen Sie das Formular aus, um ein Token anzufordern.
- Geben Sie den Ursprung des IdP als Web-Ursprung ein.
- Aktivieren Sie den Drittanbieterabgleich, um das Token mit JavaScript aus anderen Quellen zu injizieren.
- Klicken Sie auf Senden.
- Betten Sie das ausgestellte Token auf der Website eines Drittanbieters ein.
Wenn Sie das Token auf einer Drittanbieterwebsite einbetten möchten, fügen Sie der JavaScript-Bibliothek oder dem SDK des Identitätsanbieters, das vom Ursprung des Identitätsanbieters bereitgestellt wird, den folgenden Code hinzu.
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.