Actualizaciones de FedCM: Desconexión de la API y dos actualizaciones

A partir de Chrome 122, está disponible la API de Desconectar para la API de Federated Credential Management (FedCM). La API de Disconnect permite que las partes de confianza desconecten a sus usuarios de la cuenta del proveedor de identidad sin depender de cookies de terceros. Además, hay algunas actualizaciones en el control en el mismo sitio de FedCM.

API de Disconnect

Cuando un usuario crea una cuenta en un usuario de confianza (RP, el sitio que usa el proveedor de identidad para la autenticación) a través de la federación de identidades, el proveedor de identidad (IdP, el servicio que proporciona autenticación y la información de la cuenta a otras partes) suele registrar la conexión en su servidor. La conexión almacenada permite que el IdP realice un seguimiento de las RP a las que accedió el usuario y optimice su experiencia. Por ejemplo, para tener una mejor experiencia cuando el usuario regresa al RP, la cuenta de usuario con el IdP se trata como una cuenta recurrente, lo que permite funciones como la reautenticación automática y botones personalizados que muestran la cuenta utilizada.

A veces, las IdP ofrecen una API para desconectar la cuenta de un RP. Sin embargo, un flujo de desconexión se autentica y requiere las cookies del IdP. En un mundo sin cookies de terceros, cuando el usuario visita el RP, no hay una API del navegador para que este se desconecte del IdP. Debido a que puede haber varias cuentas de IdP del mismo IdP vinculado a un RP determinado, el flujo de desconexión requiere saber qué cuenta se está desconectando.

La API de Disconnect permite al usuario desconectar la cuenta del IdP del RP en el navegador y en el servidor del IdP cuando se la indica al extremo especificado. El usuario debe haber realizado la federación de identidades con la API de Federated Credential Management (FedCM). Una vez que se desconecta al usuario, se lo trata como un usuario nuevo la próxima vez que intente acceder al RP con el IdP.

Desconecta el IdP del RP

Si un usuario ya accedió al RP mediante el IdP a través de FedCM, el navegador memoriza la relación a nivel local como la lista de cuentas conectadas. El RP puede iniciar una desconexión invocando la función IdentityCredential.disconnect(). Se puede llamar a esta función desde un marco de RP de nivel superior. El RP debe pasar un configURL, el clientId que usa en el IdP y un accountHint para que se desconecte. Una sugerencia de cuenta puede ser una cadena arbitraria siempre que el extremo de desconexión pueda identificar la cuenta, por ejemplo, una dirección de correo electrónico o un ID de usuario que no coincida necesariamente con el ID de cuenta que proporcionó el extremo de la lista de cuentas:

// Disconnect an IdP account "account456" from the RP "https://idp.com/". This is invoked on the RP domain.
IdentityCredential.disconnect({
  configURL: "https://idp.com/config.json",
  clientId: "rp123",
  accountHint: "account456"
});

IdentityCredential.disconnect() muestra un Promise. Esta promesa puede arrojar una excepción por los siguientes motivos:

  • El usuario no accedió al RP mediante el IdP a través de FedCM.
  • La API se invoca desde un iframe sin la política de permisos de FedCM.
  • La configURL no es válida o falta el extremo de desconexión.
  • La verificación de la Política de Seguridad del Contenido (CSP) falla.
  • Hay una solicitud de desconexión pendiente.
  • El usuario inhabilitó FedCM en la configuración del navegador.

Cuando el extremo de desconexión del IdP muestra una respuesta, el RP y el IdP se desconectan en el navegador y se resuelve la promesa. Las cuentas de usuario que se desconectan se especifican en la respuesta desde el extremo de desconexión.

Configura el archivo de configuración del IdP

Para admitir la API de Disconnect, la AC debe admitir un extremo de desconexión y proporcionar la propiedad disconnect_endpoint y su ruta de acceso en su archivo de configuración de la AC.

{
  "accounts_endpoint": "/accounts",
  "id_assertion_endpoint": "/assertion",
  ...
  "disconnect_endpoint: "/disconnect"
}

Desconectar la cuenta en el extremo desconexión

Cuando invocas IdentityCredential.disconnect(), el navegador envía una solicitud POST de origen cruzado con cookies y un tipo de contenido application/x-www-form-urlencoded a este extremo de desconexión con la siguiente información:

Propiedad Descripción
account_hint Una sugerencia para la cuenta de IdP.
client_id El identificador de cliente de la RP.
POST /disconnect 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

Cuando recibe la solicitud, el servidor de la IdP debe hacer lo siguiente:

  1. Responde a la solicitud con CORS (uso compartido de recursos entre dominios).
  2. Verifica que la solicitud contenga un encabezado HTTP Sec-Fetch-Dest: webidentity.
  3. Haz coincidir el encabezado Origin con el origen de RP que determina client_id. Rechaza la solicitud si no coincide.
  4. Busca la cuenta que coincida con account_hint.
  5. Desconecta la cuenta de usuario de la lista de cuentas conectadas del RP.
  6. Responde al navegador con el account_id del usuario identificado en formato JSON.

Una carga útil de ejemplo de respuesta JSON se ve de la siguiente manera:

{
  "account_id": "account456"
}

Si el IdP desea que el navegador desconecte todas las cuentas asociadas con el RP, pasa una cadena que no coincida con ningún ID de cuenta, por ejemplo, "*".

Ahora se omite la verificación de /.well-known/web-identity cuando el RP y el IdP son el mismo sitio

Cuando se desarrolla un sistema FedCM, los dominios del servidor RP de prueba o etapa de pruebas pueden ser los subdominios del servidor de IdP de producción. Por ejemplo, el servidor de IdP de producción está en idp.example, y tanto el servidor de RP de etapa de pruebas como el servidor de IdP de etapa de pruebas están en staging.idp.example. Sin embargo, como el archivo conocido debe colocarse en la raíz del eTLD+1 del servidor de IdP, debe estar en idp.example/.well-known/web-identity y es el servidor de producción. Dado que no es necesariamente posible que los desarrolladores coloquen archivos en el entorno de producción durante el desarrollo, esto impide que prueben FedCM.

A partir de Chrome 122, si el dominio del RP y el del IdP son iguales, Chromeomite la verificación del archivo conocido. De esta manera, los desarrolladores podrán realizar pruebas en una situación de este tipo.

Ahora los recursos secundarios pueden establecer el estado de acceso del mismo sitio

Anteriormente, Chrome solo permitía establecer el estado de acceso (por ejemplo, con el encabezado Set-Login: logged-in) cuando la solicitud era del mismo origen con todos los ancestros. Esto impidió los accesos a través del mismo sitio que fetch() solicitaba que se configurara el estado de acceso.

Por ejemplo, piensa en un sitio web que permite que los usuarios ingresen su nombre de usuario y contraseña en idp.example, pero las credenciales se publican en login.idp.example con fetch(). No era posible registrar el estado de acceso en el navegador con la API de estado de acceso porque los dos dominios son de origen cruzado y del mismo sitio.

Con este cambio, flexibilizamos el requisito de que la API de Login Status sea del mismo sitio con todos los ancestros y permite que el ejemplo anterior establezca el estado de acceso de login.idp.example con un encabezado HTTP (Set-Login: logged-in).

Resumen

Mediante la API de Desconectar, FedCM ahora puede desconectar el RP del IdP sin depender de cookies de terceros. Para ello, llama a IdentityCredential.disconnect() en la RP. Con esta función, el navegador envía una solicitud al extremo de desconexión del IdP para que este pueda finalizar la conexión en el servidor y, luego, en el navegador.

Anunciamos que la verificación de /.well-known/web-identity se omite cuando el RP y el IdP son el mismo sitio, con fines de prueba. Además, ahora es posible configurar un estado de acceso a través de un encabezado de respuesta HTTP desde el subrecurso IdP del mismo sitio.