Compartir a través de


Casos de uso para claves de paso

En este tema se describen algunos casos de uso para las claves de paso.

Caso de uso 1: Arranque

Arranque de una cuenta en la Web.

1.1: Autenticación del usuario

Esta sección se aplica cuando el usuario de confianza (RP) aún no sabe quién controla el dispositivo cliente. No hay ningún artefacto del explorador disponible para el RP (como una cookie o un identificador de credencial en el almacenamiento local), aunque por ahora se supone que el usuario tiene una cuenta existente con el RP.

Para arrancar una cuenta, proporcione al usuario una página de inicio de sesión.

Comience pidiendo al usuario su identificador de cuenta; Normalmente, un nombre de usuario o una dirección de correo electrónico.

Iniciar sesión

Para admitir la interfaz de usuario de autorrellenar para las claves de paso, asegúrese de:

  1. Agregue el username valor y webauthn a las anotaciones de autocompletar existentes en el campo de entrada de nombre de usuario .
<div>
  <label for="username">Username:</label>
  <input name="username" id="loginform.username"
         autocomplete="username webauthn">
</div>
  1. En la carga de páginas, use una if instrucción para comprobar si la interfaz de usuario de autorrellenar (mediación condicional) está disponible y, a continuación, llame a navigator.credentials.get() con mediation: "conditional" y userVerification: "preferred".
  <script>
    (async () => {
      if (
      typeof window.PublicKeyCredential !== 'undefined'
      && typeof window.PublicKeyCredential.isConditionalMediationAvailable === 'function'
      ) {
        const available = await PublicKeyCredential.isConditionalMediationAvailable();

      if (available) {
          try {
            // Retrieve authentication options for `navigator.credentials.get()`
            // from your server.
            const authOptions = await getAuthenticationOptions();
      // This call to `navigator.credentials.get()` is "set and forget."
      // The Promise will resolve only if the user successfully interacts
      // with the browser's autofill UI to select a passkey.
      const webAuthnResponse = await navigator.credentials.get({
          mediation: "conditional",
      publicKey: {
          ...authOptions,
          // See note about userVerification below.
          userVerification: "preferred",
              }
            });
      // Send the response to your server for verification, and
      // authenticate the user if the response is valid.
      await verifyAutoFillResponse(webAuthnResponse);
          } catch (err) {
          console.error('Error with conditional UI:', err);
          }
        }
      }
    })();
  </script>

Lo anterior hará que ocurra lo siguiente:

  • Recupere las opciones de autenticación del servidor. Devuelva al menos un valor aleatorio challenge y rpId que se asocie a esta solicitud de autenticación.
  • Cuando el usuario interactúa con el campo de nombre de usuario , el explorador y la plataforma comprobarán si existe una clave de acceso (en el autenticador de plataforma) que se puede usar con el usuario de confianza.
  • Si es así, la clave de acceso se presentará al usuario como opción para elegir (junto con otras credenciales que se pueden rellenar automáticamente, como los nombres de usuario almacenados en el administrador de contraseñas del explorador). El explorador o la plataforma pueden representar una interfaz de usuario similar a la que se muestra a continuación. Aunque la apariencia exacta varía de una plataforma o factor de forma a otra:

Inicio de sesión con clave de paso

  • Si el usuario selecciona la clave de acceso, la interfaz de usuario de la plataforma guiará al usuario a través de una comprobación de usuario (a menudo basada en biometría).
  • Si el usuario pasa correctamente la comprobación del usuario, la navigator.credentials.get() llamada se realiza correctamente y devuelve una respuesta WebAuthn.
  • Si el usuario selecciona una credencial distinta de una clave de acceso, el explorador o la plataforma elige una acción adecuada diferente (por ejemplo, rellenar automáticamente el nombre de usuario) y la navigator.credentials.get() llamada no se resuelve.
  • Si el usuario selecciona la opción "Passkey from another device" (el texto exacto variará ligeramente por plataforma), el explorador o la plataforma guiará al usuario a través de una clave de seguridad FIDO2 o el flujo de autenticación entre dispositivos (CDA) para usar una clave de acceso desde su smartphone o tableta para entregar una respuesta WebAuthn a la navigator.credentials.get() llamada.
  • Envíe la respuesta de WebAuthn al servidor para su comprobación y comprobaciones de seguridad adicionales. Si todas las comprobaciones se realizan correctamente, inicie una sesión autenticada para este usuario.

Este es el motivo por el que se denomina interfaz de usuario condicional (o, más comúnmente, el modo autorrellenar la interfaz de usuario de WebAuthn): la interfaz de usuario del autenticador de plataforma que guía al usuario a través de la verificación o mediante su teléfono, solo se muestra si el usuario tiene una clave de acceso en este dispositivo (o elige la opción "otro dispositivo").

Como puede ver, en este modo, la navigator.credentials.get() llamada se realiza correctamente o no porque nunca se resuelve. Si se realiza correctamente, el resultado de la llamada revelará un identificador de usuario y una aserción de WebAuthn firmada, que el usuario de confianza (RP) usará para autenticar al usuario.

Si la llamada no se realiza correctamente, debe realizar una autenticación de usuario heredada . Obtendrá un nombre de usuario de esta primera página y, en las páginas posteriores, atenderá los desafíos de inicio de sesión más adecuados (como contraseñas, responder a desafíos de SMS, etc.) al usuario. Pueden incluir pasos de recuperación de cuentas en caso de que el usuario haya olvidado su contraseña o, de lo contrario, no pueda superar los desafíos de inicio de sesión normales. Una vez que el usuario ha superado todos los desafíos de inicio de sesión, se consideran autenticados e iniciados sesión.

Cuando el usuario aún no tenga una cuenta con el usuario de confianza (RP), normalmente proporcionará al usuario la opción en la página de inicio de sesión para crear una cuenta. Si el usuario elige esa opción, recopilará la información necesaria de ellos para abrir una nueva cuenta. Si abren correctamente una nueva cuenta, también se consideran autenticadas e iniciadas.

Una vez que el usuario haya iniciado sesión, podría ser el momento de configurar una nueva clave de acceso para ellos. Hálo para cualquiera de los casos siguientes:

  • El usuario ha arrancado su cuenta en el dispositivo pasando desafíos de inicio de sesión sin clave de acceso (por ejemplo, el uso de una contraseña).
  • El usuario acaba de crear una nueva cuenta en el usuario de confianza (RP) y se considera que inició sesión debido a eso.
  • El usuario usaba una clave de acceso, pero usaba un dispositivo diferente del que usa actualmente (seleccionando "otro dispositivo" que se muestra en el ejemplo anterior). Esto se puede confirmar inspeccionando el atributo authenticatorAttachment en el objeto PublicKeyCredential devuelto.

1.2: Autenticación entre dispositivos

Si el usuario usó una clave de acceso desde otro dispositivo (por ejemplo, una clave de seguridad de teléfono, tableta o FIDO2), la propiedad authenticatorAttachment en la respuesta de autenticación (getAssertion) tendrá el valor cross-platform.

En ese escenario, ofrezca al usuario la opción de crear una clave de acceso en su dispositivo local. Esto dará lugar a una experiencia de usuario más fluida en el futuro, ya que el usuario no será necesario para usar su otro dispositivo.

¡Configura una clave de paso en este dispositivo!

1.3: Una nota sobre la comprobación del usuario

Esta guía establece userVerification en preferred , lo que significa que la comprobación del usuario se intentará siempre que sea posible.

Es posible que algunos dispositivos, como equipos de escritorio y portátiles más antiguos, no tengan sensores biométricos. En esos dispositivos, si userVerification está establecido requireden , es posible que se le pida al usuario que escriba su contraseña de inicio de sesión del sistema para cada inicio de sesión con una clave de acceso. Y eso puede ser frustrante para ellos.

Cuando preferred se usa, algunos autenticadores de plataforma siempre requerirán una comprobación de usuario cuando el dispositivo tenga sensores biométricos, pero podría omitir la comprobación del usuario en los dispositivos sin ellos.

El resultado de la comprobación del usuario (transmitido en las marcas de datos del autenticador) reflejará el resultado real de la comprobación del usuario y siempre se debe validar con sus requisitos en el servidor.

1.4: Participación del usuario en las claves de acceso

En primer lugar, compruebe que el usuario está suficientemente autenticado mediante otros métodos de inicio de sesión, incluida la autenticación multifactor.

En segundo lugar, asegúrese de que el dispositivo y el combo del sistema operativo (SO) del usuario admiten claves de acceso mediante una llamada a:

PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()

Si se admiten claves de acceso, devolverá true. Si no se admiten, devolverá falsey debe anular el flujo de inscripción de clave de acceso.

Proporcione una página o modal/intersticial o "venta ascendente" al usuario que les ofrece para crear una clave de acceso:

¡Inicio de sesión más rápido y seguro con claves de paso!

Sugerencia

Para asegurarse de que el usuario da su consentimiento totalmente informado, considere la posibilidad de mostrar (o vincular a) descripciones más largas que explican que todos los usuarios que pueden desbloquear el dispositivo actual podrán acceder a la cuenta en el usuario de confianza (RP).

Si el usuario da su consentimiento, llame a navigator.credentials.create() con las opciones que se muestran en el ejemplo siguiente:

navigator.credentials.create({
  publicKey: {
    rp: {
      // User-friendly name of your service.
      name: "Passkeys Developer",
      // Relying party (RP) identifier (hostname/FQDN).
      id: passkeys.contoso"
    },

    user: {
      // Persistent, unique identifier for the user account in your backend.
      id: Uint8Array.from("0525bc79-5a63-4e47-b7d1-597e25f5caba", c => c.charCodeAt(0)),
      // User-friendly identifier often displayed to the user (for example, email address).
      name: "amanda@contoso.com",
      // Human-readable display name, sometimes displayed by the client.
      displayName: "Amanda Brady"
    },
    // The challenge is a buffer of cryptographically random bytes generated on your backend,
    // and should be tightly bound to the current user session.
    challenge: Uint8Array.from("XZJscsUqtBH7ZB90t2g0EbZTZYlbSRK6lq7zlN2lJKuoYMnp7Qo2OLzD7xawL3s", c => c.charCodeAt(0)),
    pubKeyCredParams: [
      // An array of objects describing what public key types are acceptable to a server.
      {
        "type": "public-key",
        "alg": -7 // EC P256
      },
      {
        "type": "public-key",
        "alg": -257 // RSA
      }
    ],
    excludeCredentials: [
      // Array of credential IDs for existing passkeys tied to the user account.
      // This avoids creating a new passkey in an authenticator that already has 
      // a passkey tied to the user account.
      {
        // Example only.
        type: "public-key",
        id: new Uint8Array([21, 31, 56, ...]).buffer
      },
      {
        // Example only.
        type: "public-key",
        id: new Uint8Array([21, 31, 56, ...]).buffer
      }
    ],
    authenticatorSelection: {
      // Tells the authenticator to create a passkey.
      residentKey: "required",
      // Tells the client/authenticator to request user verification where possible;
      // for example, a biometric or a device PIN.
      userVerification: "preferred"
    },
    "extensions": {
      // Returns details about the passkey.
      "credProps": true
    }
  }
})

Nota:

Se recomienda que la mayoría de los usuarios de confianza (CSP) no especifiquen el parámetro attestation de transmisión de atestación (por lo tanto, el valor predeterminado es ninguno) o, en su lugar, use explícitamente el valor indirect. Esto garantiza la experiencia de usuario más simplificada (es probable que las plataformas obtengan consentimiento del usuario para otros tipos de transmisión de atestación, lo que probablemente da lugar a una mayor fracción de creaciones de credenciales incorrectas debido a que los usuarios cancelan la creación).

Cuando se resuelva la llamada a WebAuthn, envíe la respuesta al servidor y asocie la clave pública y el identificador de credencial devueltos a la cuenta de usuario autenticada anteriormente.

Caso de uso 2: Reauthentication

El uso de claves de acceso para una reautenticación puede ser necesario por cualquiera de los siguientes motivos:

  • El usuario ha cerrado la sesión y ahora quiere volver a iniciar sesión.
  • La sesión del usuario expiró debido a la inactividad y el usuario quiere iniciar sesión de nuevo.
  • El usuario está a punto de realizar una acción confidencial y debe volver a confirmar el control sobre la sesión del usuario.

Para volver a autenticar al usuario en cada una de estas situaciones, usará las claves de acceso que configuró en el caso de uso anterior. La llamada API de WebAuthn es la misma en los tres casos, pero el tratamiento de la interfaz de usuario que proporcione es ligeramente diferente. Dado que usted especifica la cuenta concreta, la plataforma no pedirá al usuario que seleccione otra cuenta en el servicio.

2.1: Acciones confidenciales

Echemos un vistazo primero a la interfaz de usuario por el tercer motivo: cuando es el momento de volver a autenticarse para una acción confidencial, compruebe si tiene un identificador de credencial para al menos una clave de acceso para el usuario.

Si no hay ningún identificador de credencial disponible, proporcione un desafío de inicio de sesión tradicional adecuado para la reautenticación, por ejemplo:

Asegúrese de que es usted 1

Sugerencia

Se recomienda que, en esta página de desafío de inicio de sesión, los usuarios no puedan cambiar su identificador de cuenta. Además, el desafío de inicio de sesión debe ser algo que no pueda pasar un usuario no autorizado del dispositivo.

Por otro lado, si encuentra al menos un identificador de credencial de clave de acceso para el usuario, puede usar claves de acceso para la reautenticación:

Asegúrese de que es usted 2

Cuando el usuario esté listo (en el ejemplo anterior, cuando haga clic en el botón "Ir"), llame a navigator.credentials.get()y pase todos los identificadores de credenciales de clave de acceso del usuario:

navigator.credentials.get({
  publicKey: {
    challenge: ...,
    rpId: ...,
     allowCredentials: [{
      type: "public-key",      
      id: new UInt8Array([21, 31, 56, ...]).buffer,
    }, {
      type: "public-key",
      id: new UInt8Array([21, 31, 56, ...]).buffer,
    }, {
      ...
    }],
    // see note below
    userVerification: "preferred", 
  }
});

Nota:

Asegúrese de leer las instrucciones sobre userVerification del caso de uso anterior.

Si en su lugar el usuario hace clic en "Probar otra manera", debe ofrecerles otros métodos de inicio de sesión (contraseña, etc.) para volver a autenticarlos (suponiendo que el usuario tenga otros métodos de inicio de sesión disponibles para ellos).

2.2: Sesiones expiradas y cierre de sesión

Ahora examinaremos el caso en el que se desencadena la reautenticación porque el usuario ha cerrado sesión o el usuario de confianza (RP) ha expirado la sesión del usuario. Para facilitar esto, el RP tendría que mantener algún tipo de estado de sesión de usuario recordándoles de la cuenta que anteriormente había iniciado sesión, incluso cuando consideran que el usuario ha cerrado sesión (que podría lograrse mediante artefactos del explorador, como cookies o almacenamiento local).

Nota:

Un usuario de confianza (RP) puede optar por tratar el cierre de sesión como una acción completa y, por tanto, eliminar todas las referencias a la identidad del usuario. Este rp debe tratar un inicio de sesión posterior como un arranque de cuenta y repetir los pasos explicados anteriormente.

Usted, como RP, podría servir una página de inicio de sesión como esta:

¡Bienvenido! 1

Si el usuario hace clic en "Usar una cuenta diferente", debe escribir un flujo de arranque de la cuenta, como se explica en el caso de uso anterior, repitiendo los pasos allí, donde la plataforma permitirá al usuario seleccionar qué cuenta quiere usar.

Nota:

En ese caso, también debe proporcionar al usuario la capacidad de quitar completamente la cuenta sugerida de aparecer en la página de inicio de sesión.

Pero si el usuario hace clic en el botón "Iniciar sesión como", compruebe si tiene al menos un identificador de credencial de clave de acceso asociado al usuario. Si no hay ningún identificador de credencial disponible, proporcione un desafío de inicio de sesión tradicional adecuado para la reautenticación, por ejemplo:

¡Bienvenido! 2

Por otro lado, si encuentra al menos un identificador de credencial de clave de acceso para el usuario, puede usar claves de acceso para la reautenticación:

¡Bienvenido! 3

Cuando el usuario esté listo (en el ejemplo anterior, cuando haga clic en el botón "Ir"), llame a navigator.credentials.get(), exactamente como se muestra (es decir, pasando todos los identificadores de credenciales de clave de acceso del usuario).

Si en su lugar el usuario hace clic en "Probar otra manera", debe ofrecerles otros métodos de inicio de sesión (contraseña, etc.) para volver a autenticarlos (suponiendo que el usuario tenga otros métodos de inicio de sesión disponibles para ellos).

Pasos siguientes

A continuación, consulte Herramientas y bibliotecas para claves de paso.

Más información