A partir de Chrome 126, los desarrolladores pueden comenzar a ejecutar una prueba de origen para un paquete de de escritorio de la API de Federated Credential Management (FedCM) que permiten Casos de uso de autorización. El paquete consta de la API de Continuation y las API de Parameters, que habilita una experiencia similar a un flujo de autorización de OAuth que involucre un diálogo de permisos proporcionado por el proveedor de identidad (IdP). El paquete también incluye otros cambios, como la API de Fields, varias configURLs y la configuración Etiquetas de la cuenta. A partir de Chrome 126, también presentamos una prueba de origen para el API de Storage Access (SAA), que otorga automáticamente solicitudes de SAA si el usuario accedió correctamente con FedCM en el pasado.
Prueba de origen: paquete de la API de Continuation de FedCM
El paquete de la API de Continuation de FedCM consta de varias extensiones de FedCM:
- API de Continuation
- API de Parameters
- API de Fields
- Varias configURLs
- Etiquetas personalizadas de la cuenta
API de Continuation
Puedes ver una demostración de la API en Glitch.
La API de Continuation permite la Aserción de ID del IdP extremo en De manera opcional, muestra una URL que FedCM renderizará para permitir que el usuario continúe una y el flujo de acceso de varios pasos. Esto permite que el IdP solicite al usuario que otorgue el permisos de la parte de confianza (RP) más allá de lo posible en la IU existente de FedCM como el acceso a los recursos del servidor del usuario.
Normalmente, el extremo de aserción de ID devuelve un token necesario para autenticación.
{
"token": "***********"
}
Sin embargo, con la API de Continuation, la aserción de ID
extremo puede
mostrar una propiedad continue_on
que incluya una ruta de acceso absoluta o una respuesta
ruta de acceso al extremo de aserción de 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=..."
}
En cuanto el navegador reciba la respuesta continue_on
, aparecerá una nueva ventana emergente
se abre y lleva al usuario a la ruta especificada.
Después de que el usuario interactúe con la página, por ejemplo, si otorga más permisos
para compartir información adicional con el RP, la página del IdP puede llamar
IdentityProvider.resolve()
para resolver el original
navigator.credentials.get()
y muestra un token como argumento.
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);
});
El navegador luego cierra la ventana emergente por sí mismo y devuelve el token a la API. llamador.
Si el usuario rechaza la solicitud, puedes llamar para cerrar la ventana
IdentityProvider.close()
IdentityProvider.close();
Si, por algún motivo, el usuario cambió su cuenta en la ventana emergente (por ejemplo, el IdP ofrece la opción para cambiar de usuario o en casos de delegación), la resolución call toma un segundo argumento opcional que permite algo como lo siguiente:
IdentityProvider.resolve(token, {accountId: '1234');
API de Parameters
La API de Parameters permite el RP para proporcionar parámetros adicionales a la aserción de ID extremo. Con la API de Parameters, las RP pueden pasar parámetros adicionales al IdP para solicitar permisos para otros recursos además del acceso básico. El usuario autorizaría estos permisos a través de un flujo de UX controlado por IdP que se inicia a través del API de Continuation.
Para usar la API, agrega parámetros a la propiedad params
como un objeto en el
Llamada de 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',
}
},
}
});
A los nombres de las propiedades del objeto params
se les antepone param_
. En la
ejemplo anterior, la propiedad de los parámetros contiene IDP_SPECIFIC_PARAM
como '1'
, foo
como 'BAR'
, ETC
como 'MOAR'
y scope
como 'calendar.readonly photos.write'
.
Esto se traducirá como
param_IDP_SPECIFIC_PARAM=1¶m_foo=BAR¶m_ETC=MOAR¶m_scope=calendar.readonly%20photos.write
en el cuerpo HTTP de la solicitud:
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
Obtén permisos de forma dinámica
En general, para los usuarios es más útil solicitar permisos cuando están en lugar de cuando el desarrollador considere que son más fáciles de implementar. Para pedir permiso para acceder a una cámara cuando el usuario está a punto de tomar se prefiere una foto antes que pedir permiso en cuanto el usuario llega a la sitio web. La misma práctica se aplica a los recursos del servidor. Solicitar solo permisos cuando se necesitan para el usuario. Esto se denomina "autorización dinámica".
Para solicitar autorización de forma dinámica con FedCM, el IdP puede hacer lo siguiente:
- Llama a
navigator.credentials.get()
con los parámetros necesarios que el IdP puede comprender, comoscope
. - La aserción de ID
extremo
Confirma que el usuario ya accedió y responde con una URL
continue_on
. - El navegador abre una ventana emergente con la página de permisos del IdP que solicita permiso adicional que coincida con los alcances solicitados.
- Una vez que el IdP lo autoriza a través de
IdentityProvider.resolve()
, la ventana se se cierra y la llamada original anavigator.credentials.get()
del RP obtiene un el token correspondiente o un código de autorización para que el RP pueda intercambiarlo con un token de acceso adecuado.
API de Fields
La API de Campos permite que el RP haga lo siguiente: declarar atributos de la cuenta que se solicitarán desde el IdP para que el navegador pueda renderizar una IU de divulgación adecuada en el diálogo de la FedCM es responsabilidad del IdP para incluir los campos solicitados en el token devuelto. Considera esta solicitud un "perfil básico" en OpenID Connect en comparación con los "alcances" en OAuth.
Para usar la API de Fields, agrega parámetros a la propiedad fields
como un array en el
Llamada de navigator.credentials.get()
. Los campos pueden contener 'name'
y 'email'
.
y 'picture'
por ahora, pero se puede expandir para incluir más valores en el
en el futuro.
Una solicitud con fields
se vería de la siguiente manera:
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 solicitud HTTP a la aserción de ID
extremo
incluye el parámetro fields
especificado en el RP, con el disclosure_text_shown
configurado como true
si no es un usuario recurrente, y los campos que
navegador divulgado al usuario en un parámetro 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 el RP necesita acceder a cualquier dato adicional del IdP, como acceso a un
calendario, se debe controlar con un parámetro personalizado, tal como se mencionó anteriormente. El
El IdP muestra una URL continue_on
para solicitar permiso.
Si fields
es un array vacío, la solicitud se verá de la siguiente manera:
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
es un array vacío, el usuario-agente omitirá la IU de divulgación.
Esto ocurre incluso si la respuesta de las cuentas
extremo
no contiene un ID de cliente que coincida con el RP en approved_clients
.
En este caso, el disclosure_text_shown
enviado a la aserción de ID
extremo es
false en el cuerpo 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
Varias configURL
Varias configURLs permiten los IdP
para admitir varios archivos de configuración para un IdP, especificando
accounts_endpoint
y login_url
en la conocida
archivo igual
que los archivos de configuración.
Si se agregan accounts_endpoint
y login_url
al archivo conocido, el
provider_urls
se ignoran para que el IdP pueda admitir varios archivos de configuración.
Si no es así, provider_urls
continúa sucediendo para que retroceda
compatibles.
El archivo conocido que admite varias configURL puede verse de la siguiente manera:
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
Esto nos permite lo siguiente:
- Cómo mantener la compatibilidad con versiones anteriores y posteriores con archivos conocidos existentes y la versión anterior de los navegadores que ya están implementados.
- Tener una cantidad arbitraria de archivos de configuración, siempre que todos apunten a la
mismo
accounts_endpoint
ylogin_url
. - No tienen la oportunidad de que la entropía se agregue a la solicitud de recuperación con credenciales
hecho a
accounts_endpoint
, ya que debe especificarse en el “.well-known” a nivel de organización.
La compatibilidad con varias configURL es opcional, y la FedCM existente las implementaciones pueden permanecer iguales.
Etiquetas personalizadas de la cuenta
Las etiquetas de cuenta personalizadas permiten que FedCM
IdP para anotar las cuentas, de modo que los RP puedan filtrarlas especificando la etiqueta en
un archivo de configuración. Se ha podido aplicar un filtro similar con la opción Domain Hint
la API y el campo Login
API de Hint con la especificación
en la llamada navigator.credentials.get()
, pero las etiquetas personalizadas de la cuenta
puede filtrar usuarios especificando el archivo de configuración, lo cual es muy útil cuando
se usan varias configURLs. Las etiquetas personalizadas de la cuenta son
también difieren en que se proporcionan desde el servidor IdP, y no desde
la parte restringida, como sugerencias de acceso o de dominio.
Ejemplo
Un IdP admite dos configURLs para consumidores y empresas, respectivamente. El
el archivo de configuración del consumidor tiene una etiqueta 'consumer'
, y el archivo de configuración de la empresa
tiene una etiqueta 'enterprise'
.
Con esta configuración, el archivo conocido incluye accounts_endpoint
y
login_url
para permitir varias configURL.
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
Cuando se proporciona accounts_endpoint
en el archivo conocido, el
Se ignoran provider_urls
. La parte restringida puede apuntar directamente a la configuración respectiva
de la llamada a navigator.credentials.get()
.
El archivo de configuración del consumidor se encuentra en https://idp.example/fedcm.json
, que incluye
La propiedad accounts
que especifica 'consumer'
con 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"
}
}
El archivo de configuración de la empresa se encuentra en https://idp.example/enterprise/fedcm.json
,
que incluye la propiedad accounts
, que especifica 'enterprise'
con el elemento
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"
}
}
Las cuentas comunes del IdP
extremo
(en este ejemplo, https://idp.example/accounts
) muestra una lista de cuentas que
incluye una propiedad de etiquetas con labels
asignado en un array para cada cuenta.
La siguiente es una respuesta de ejemplo para un usuario que tiene dos cuentas. Una es para
consumidor y la otra es para empresas:
{
"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"]
}]
}
Si una parte restringida quiere permitir que los usuarios de 'enterprise'
accedan, puede especificar la
'enterprise'
configURL 'https://idp.example/enterprise/fedcm.json'
en la
Llamada de navigator.credentials.get()
:
let { token } = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
nonce: '234234',
configURL: 'https://idp.example/enterprise/fedcm.json',
},
}
});
Como resultado, solo el ID de la cuenta de '4567'
está disponible para que el usuario lo firme
en el que te etiquetaron. El navegador oculta el ID de la cuenta de '123'
de forma silenciosa para que el usuario
no se proporcionarán con una cuenta que no sea compatible con el IdP en este sitio.
Prueba de origen: FedCM como indicador de confianza para la API de Storage Access
Chrome 126 está iniciando una prueba de origen de FedCM como indicador de confianza para el Acceso al almacenamiento API Con este cambio, un permiso previo otorgado a través de la FedCM se convierte en un motivo válido aprobar automáticamente una solicitud de acceso al almacenamiento por parte de Storage Access APIs.
Esto es útil cuando un iframe incorporado desea acceder a recursos personalizados: por ejemplo, si idp.example está incorporado en rp.example y necesita mostrar un recurso personalizado. Si el navegador restringe el acceso a las cookies de terceros, incluso si el usuario accede a rp.example mediante idp.example con FedCM, el El iframe idp.example incorporado no podrá solicitar recursos personalizados porque las solicitudes no incluirán cookies de terceros.
Para lograr esto, idp.example necesita obtener un permiso de acceso al almacenamiento a través de su iframe incorporado en el sitio web. Esto solo se puede obtener a través de un solicitud de permiso.
Con FedCM como indicador de confianza para el acceso al almacenamiento API, Las verificaciones de permisos de la API de Storage Access no solo aceptan el otorgamiento de permisos que se otorga mediante una solicitud de acceso al almacenamiento, pero también el otorgamiento de permisos que otorga un Mensaje de 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();
Una vez que el usuario accede con FedCM, el permiso se otorga automáticamente, siempre y cuando la autenticación de FedCM esté activa. Esto significa que, cuando el usuario se desconecta, cuando solicites permiso, aparecerá un mensaje.
Participar en la prueba de origen
Puedes probar el paquete de la API de FedCM Continuation de forma local activando una
marca
chrome://flags#fedcm-authz
en Chrome 126 o versiones posteriores. También puedes probar la FedCM
como indicador de confianza para la API de Storage Access de forma local activando
#fedcm-with-storage-access-api
en Chrome 126 o versiones posteriores.
Estas funciones también están disponibles como pruebas de origen. Las pruebas de origen te permiten probar funciones nuevas y proporcionar comentarios sobre su usabilidad, practicidad y eficacia. Para obtener más información, consulta Comienza a usar las pruebas de origen.
Para probar el origen del paquete de la API de Continuation de FedCM prueba, Crea dos tokens de prueba de origen:
- Regístrate para la prueba. Incorpora el token en el IdP origen.
- Regístrate en la prueba de origen con la casilla de verificación correspondiente a terceros marcada. Sigue las instrucciones que se indican en Cómo registrar una prueba de origen de terceros para la RP para incorporar el token de la parte restringida
Si quieres habilitar la API de Continuation junto con el botón de flujo, habilita el modo Button Origen de la API prueba y
- Regístrate en la prueba de origen como un tercero. Sigue las instrucciones que se indican en Registrar una prueba de origen de terceros para que se incorpore la parte restringida el token para el RP.
Para probar el FedCM como indicador de confianza para el origen de la API de Storage Access prueba:
- Regístrate en la prueba de origen. Incorpora el token en el IdP origen.
La prueba de origen del paquete de la API de Continuation y el FedCM como indicador de confianza para el La prueba de origen de la API de Storage Access está disponible a partir de la versión 126 de Chrome.
Registra una prueba de origen de terceros para el RP
- Ve a la página de registro de la prueba de origen.
- Haz clic en el botón Register y completa el formulario para solicitar un token.
- Ingresa el origen del IdP como Web Origin.
- Verifica la coincidencia con terceros para insertar el token con JavaScript en otros orígenes.
- Haz clic en Enviar.
- Incorpora el token emitido en el sitio web de un tercero.
Para incorporar el token en un sitio web de terceros, agrega el siguiente código al IdP La biblioteca de JavaScript o el SDK que se entrega desde el origen del IdP.
const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);
Reemplaza TOKEN_GOES_HERE
por tu propio token.