La API de Web Authentication, también conocida como WebAuthn, permite que los servidores usen criptografía de clave pública, en lugar de contraseñas, para registrar y autenticar usuarios. Para ello, habilita la integración entre estos servidores y autenticadores seguros. Estos autenticadores pueden ser dispositivos físicos dedicados (p.ej., llaves de seguridad) o integrados en plataformas (p.ej., lectores de huellas dactilares). Puedes obtener más información sobre WebAuthn en webauthn.guide.
Problemas de los desarrolladores
Antes de este proyecto, WebAuthn no contaba con compatibilidad con la depuración nativa en Chrome. Un desarrollador que compilaba una app que usaba WebAuth necesitaba acceso a autenticadores físicos. Esto fue especialmente difícil por dos razones:
Existen muchos tipos diferentes de autenticadores. La depuración de la amplia variedad de parámetros de configuración y capacidades exigía que el desarrollador tuviera acceso a muchos autenticadores diferentes, a veces costosos.
Los autenticadores físicos son seguros por diseño. Por lo tanto, suele ser imposible inspeccionar su estado.
Para facilitar este proceso, agregamos compatibilidad con la depuración directamente en Chrome DevTools.
Solución: Una nueva pestaña de WebAuthn
La pestaña WebAuthn de DevTools facilita mucho la depuración de WebAuthn, ya que permite a los desarrolladores emular estos autenticadores, personalizar sus capacidades y, además, inspeccionar sus estados.
Implementación
Agregar compatibilidad con la depuración a WebAuthn fue un proceso de dos partes.
Parte 1: Agrega el dominio de WebAuthn al protocolo de Chrome DevTools
Primero, implementamos un nuevo dominio en el protocolo de DevTools de Chrome (CDP) que se conecta a un controlador que se comunica con el backend de WebAuthn.
El CDP conecta el frontend de DevTools con Chromium. En nuestro caso, usamos los actos de dominio de WebAuthn para establecer un puente entre la pestaña WebAuthn de DevTools y la implementación de WebAuthn de Chromium.
El dominio de WebAuthn permite habilitar y deshabilitar el entorno del autenticador virtual, que desconecta el navegador del descubrimiento real del autenticador y, en su lugar, conecta un descubrimiento virtual.
También exponemos métodos en el dominio que actúan como una capa delgada para las interfaces existentes de Virtual Authenticator y Virtual Discovery, que forman parte de la implementación de WebAuthn de Chromium. Estos métodos incluyen agregar y quitar autenticadores, así como crear, obtener y borrar sus credenciales registradas.
(lee el código).
Parte 2: Compila la pestaña para el usuario
En segundo lugar, creamos una pestaña para el usuario en el frontend de DevTools. La pestaña se compone de una vista y un modelo. Un agente generado automáticamente conecta el dominio con la pestaña.
Si bien hay 3 componentes necesarios, solo debemos preocuparnos por dos de ellos: el modelo y la vista. El tercer componente, el agente, se genera automáticamente después de agregar el dominio. En resumen, el agente es la capa que lleva las llamadas entre el frontend y la CDP.
El modelo
El modelo es la capa de JavaScript que conecta el agente y la vista. En nuestro caso, el modelo es bastante simple. Toma comandos de la vista, compila las solicitudes de modo que la CDP pueda consumirlas y, luego, las envía a través del agente. Por lo general, estas solicitudes son unidireccionales y no se envía información a la vista.
Sin embargo, a veces pasamos una respuesta del modelo para proporcionar un ID para un autenticador creado recientemente o para mostrar las credenciales almacenadas en un autenticador existente.
(lee el código).
La vista
Usamos la vista para proporcionar la interfaz de usuario que un desarrollador puede encontrar cuando accede a DevTools. Contiene los siguientes elementos:
- Una barra de herramientas para habilitar el entorno del autenticador virtual.
- Una sección para agregar autenticadores.
- Es una sección para los autenticadores creados.
(lee el código).
Barra de herramientas para habilitar el entorno del autenticador virtual
Dado que la mayoría de las interacciones del usuario se realizan con un autenticador a la vez en lugar de con toda la pestaña, la única funcionalidad que proporcionamos en la barra de herramientas es activar y desactivar el entorno virtual.
¿Por qué es necesario esto? Es importante que el usuario tenga que activar o desactivar el entorno de forma explícita, ya que, de esta manera, se desconecta el navegador del descubrimiento real de Authenticator. Por lo tanto, mientras esté activado, no se reconocerán los autenticadores físicos conectados, como un lector de huellas dactilares.
Decidimos que un botón de activación explícito brinda una mejor experiencia del usuario, especialmente para quienes ingresan a la pestaña WebAuthn sin esperar que se inhabilite el descubrimiento real.
Agrega la sección Autenticador
Cuando habilitamos el entorno del autenticador virtual, le presentamos al desarrollador un formulario intercalado que le permite agregar un autenticador virtual. En este formulario, proporcionamos opciones de personalización que permiten al usuario decidir el protocolo y los métodos de transporte del autenticador, así como si el autenticador admite claves residentes y verificación de usuarios.
Una vez que el usuario hace clic en Agregar, estas opciones se agrupan y se envían al modelo que realiza la llamada para crear un autenticador. Una vez que se complete, el frontend recibirá una respuesta y, luego, modificará la IU para incluir el autenticador creado recientemente.
Vista del Autenticador
Cada vez que se emula un autenticador, agregamos una sección a la vista del autenticador para representarlo. Cada sección del autenticador incluye un nombre, un ID, opciones de configuración, botones para quitar el autenticador o activarlo, y una tabla de credenciales.
El nombre del autenticador
El nombre del autenticador se puede personalizar y, de forma predeterminada, es "Authenticator" concatenado con los últimos 5 caracteres de su ID. Originalmente, el nombre del autenticador era su ID completo y no se podía cambiar. Implementamos nombres personalizables para que el usuario pueda etiquetar el autenticador según sus capacidades, el autenticador físico que está destinado a emular o cualquier sobrenombre que sea más fácil de entender que un ID de 36 caracteres.
Tabla de credenciales
Agregamos una tabla a cada sección del autenticador que muestra todas las credenciales registradas por un autenticador. En cada fila, proporcionamos información sobre una credencial, así como botones para quitarla o exportarla.
Actualmente, recopilamos la información para completar estas tablas mediante sondeos en la CDP para obtener las credenciales registradas de cada autenticador. En el futuro, planeamos agregar un evento para la creación de credenciales.
El botón Activo
También agregamos un botón de selección Activo a cada sección del autenticador. El autenticador que está configurado como activo será el único que detecte y registre las credenciales. Sin esto, el registro de credenciales que se proporcionan a varios autenticadores no es determinista, lo que sería un error fatal cuando se intente probar WebAuthn con ellos.
Implementamos el estado activo con el método SetUserPresence en los autenticadores virtuales. El método SetUserPresence establece si las pruebas de presencia del usuario se realizan correctamente para un autenticador determinado. Si lo desactivamos, un autenticador no podrá escuchar las credenciales. Por lo tanto, si nos aseguramos de que esté activado para un máximo de un autenticador (el que se establece como activo) y de inhabilitar la presencia del usuario para todos los demás, podemos forzar el comportamiento determinista.
Un desafío interesante que enfrentamos cuando agregamos el botón activo fue evitar una condición de carrera. Considera la siguiente situación:
El usuario hace clic en el botón de selección Activo para el autenticador X y envía una solicitud al CDP para establecer X como activo. El botón de selección Activo para X está seleccionado y todos los demás están sin seleccionar.
Inmediatamente después, el usuario hace clic en el botón de selección Activo para el autenticador Y y envía una solicitud al CDP para establecer Y como activo. El botón de selección Activo para Y está seleccionado, y todos los demás, incluido X, están desmarcados.
En el backend, se completa y resuelve la llamada para establecer Y como activo. Y ahora está activo y todos los demás autenticadores no lo están.
En el backend, se completa y resuelve la llamada para establecer X como activo. X ahora está activo y todos los demás autenticadores, incluida Y, no lo están.
Ahora, la situación resultante es la siguiente: X es el autenticador activo. Sin embargo, el botón de selección Activo para X no está seleccionado. Y no es el autenticador activo. Sin embargo, el botón de selección Activo para Y está seleccionado. Hay una discrepancia entre el frontend y el estado real de los autenticadores. Por supuesto, eso es un problema.
Nuestra solución: Establecer una pseudocomunicación bidireccional entre los botones de selección y el autenticador activo. Primero, mantenemos una variable activeId
en la vista para hacer un seguimiento del ID del autenticador activo actualmente. Luego, esperamos a que se devuelva la llamada para establecer un autenticador activo y, luego, configuramos activeId
en el ID de ese autenticador. Por último, recorremos en bucle cada sección del autenticador. Si el ID de esa sección es igual a activeId
, configuramos el botón como seleccionado. De lo contrario, configuramos el botón como no seleccionado.
A continuación, te mostramos cómo se ve:
async _setActiveAuthenticator(authenticatorId) {
await this._clearActiveAuthenticator();
await this._model.setAutomaticPresenceSimulation(authenticatorId, true);
this._activeId = authenticatorId;
this._updateActiveButtons();
}
_updateActiveButtons() {
const authenticators = this._authenticatorsView.getElementsByClassName('authenticator-section');
Array.from(authenticators).forEach(authenticator => {
authenticator.querySelector('input.dt-radio-button').checked =
authenticator.getAttribute('data-authenticator-id') === this._activeId;
});
}
async _clearActiveAuthenticator() {
if (this._activeId) {
await this._model.setAutomaticPresenceSimulation(this._activeId, false);
}
this._activeId = null;
}
Métricas de uso
Queríamos hacer un seguimiento del uso de esta función. Inicialmente, se nos ocurrieron dos opciones.
Cuenta cada vez que se abrió la pestaña WebAuthn en DevTools. Esta opción podría generar un recuento excesivo, ya que alguien podría abrir la pestaña sin usarla.
Realiza un seguimiento de la cantidad de veces que se activó la casilla de verificación "Habilitar entorno del autenticador virtual" en la barra de herramientas. Esta opción también tenía un posible problema de recuento excesivo, ya que algunos usuarios pueden activar y desactivar el entorno varias veces en la misma sesión.
En última instancia, decidimos usar la última opción, pero restringir el recuento con una verificación para ver si el entorno ya se había habilitado en la sesión. Por lo tanto, solo aumentaríamos el recuento en 1, independientemente de cuántas veces el desarrollador haya activado el entorno. Esto funciona porque se crea una sesión nueva cada vez que se vuelve a abrir la pestaña, lo que restablece la verificación y permite que la métrica se incremente nuevamente.
Resumen
Gracias por leer. Si tienes alguna sugerencia para mejorar la pestaña WebAuthn, infórmanos al respecto mediante un error.
Estos son algunos recursos si quieres obtener más información sobre WebAuthn:
- Documento de diseño del frontend de DevTools de WebAuthn
- Documento de diseño de la API de pruebas de Web Authentication
- Especificación de la API de Web Authentication (WebAuthn)
- Explicación y guía de WebAuthn
Descarga los canales de vista previa
Considera usar Chrome Canary, Dev o Beta como tu navegador de desarrollo predeterminado. Estos canales de versión preliminar te brindan acceso a las funciones más recientes de DevTools, te permiten probar las APIs de plataformas web de vanguardia y te ayudan a encontrar problemas en tu sitio antes que tus usuarios.
Comunícate con el equipo de Chrome DevTools
Usa las siguientes opciones para hablar sobre las funciones nuevas, las actualizaciones o cualquier otro tema relacionado con DevTools.
- Envíanos tus comentarios y solicitudes de funciones a crbug.com.
- Informa un problema de DevTools con Más opciones > Ayuda > Informar un problema de DevTools en DevTools.
- Twittea a @ChromeDevTools.
- Deja comentarios en los videos de YouTube sobre las novedades de DevTools o en los videos de YouTube sobre sugerencias de DevTools.