Autenticación en wearables: Administrador de credenciales

Las apps para Wear OS pueden ejecutarse de manera independiente sin una app complementaria. Es decir, una app para Wear OS necesita administrar la autenticación por su cuenta cuando accede a datos de Internet. Sin embargo, el tamaño pequeño de la pantalla del reloj y las capacidades de entrada reducidas limitan las opciones de autenticación que puede usar una app para Wear OS.

En esta guía, se proporcionan instrucciones para el método de autenticación recomendado para las apps para Wear OS, Credential Manager.

Para obtener más información sobre cómo diseñar una buena experiencia de acceso, consulta la guía de UX de acceso.

Consideraciones preliminares

Antes de comenzar la implementación, ten en cuenta los siguientes puntos.

Modo de invitado

No se solicita autenticación para todas las funcionalidades. En su lugar, proporciona tantas funciones como sea posible para el usuario, sin necesidad de que acceda.

Es posible que los usuarios descubran e instalen tu app para Wear sin haber usado la app para dispositivos móviles. Por lo tanto, es posible que no tengan una cuenta y no conozcan las funciones que ofrece. Asegúrate de que la funcionalidad del modo de invitado muestre con precisión las funciones de tu app.

Es posible que algunos dispositivos permanezcan desbloqueados por más tiempo

En los dispositivos compatibles que ejecutan Wear OS 5 o versiones posteriores, el sistema detecta si el usuario lleva el dispositivo en la muñeca. Si el usuario desactiva la detección de muñeca y luego se quita el dispositivo de la muñeca, el sistema lo mantiene desbloqueado por un período más largo de lo normal.

Si tu app requiere un nivel de seguridad más alto, por ejemplo, cuando muestra datos potencialmente sensibles o privados, primero verifica si la detección de muñeca está habilitada:

fun isWristDetectionAutoLockingEnabled(context: Context): Boolean {
    // Use the keyguard manager to check for the presence of a lock mechanism
    val keyguardManager = context.getSystemService<KeyguardManager>()
    val isSecured = keyguardManager?.isDeviceSecure == true

    // Use OEM-specific system settings to verify that on-body autolock is enabled.
    val isWristDetectionOn = android.provider.Settings.Global.getInt(
        context.contentResolver, PIXEL_WRIST_AUTOLOCK_SETTING_STATE,
        0
    ) == 1

    return isSecured && isWristDetectionOn
}

Si el valor que se muestra de este método es false, solicita al usuario que acceda a una cuenta en tu app antes de mostrar contenido específico del usuario.

Credential Manager

Credential Manager es la API recomendada para la autenticación en Wear OS. Proporciona un entorno más seguro para que los usuarios accedan a las aplicaciones de Wear OS en una configuración independiente, sin necesidad de un teléfono vinculado conectado y sin tener que recordar su contraseña.

En este documento, se describe la información que los desarrolladores necesitan para implementar una solución de Credential Manager con los mecanismos de autenticación estándar que aloja, que son los siguientes:

  • Llaves de acceso
  • Contraseñas
  • Identidades federadas (como Acceder con Google)

En esta guía, también se proporcionan instrucciones para migrar los otros métodos de autenticación aceptables de Wear OS (intercambio de tokens de la capa de datos y OAuth) como copias de seguridad para Credential Manager, y se dan instrucciones especiales para controlar la transición del botón de Acceder con Google independiente, que ahora está obsoleto, a la versión integrada de Credential Manager.

Limitaciones y diferencias de Wear OS

Los desarrolladores deben tener en cuenta las siguientes limitaciones y diferencias en Wear OS:

  • Credential Manager está disponible en Wear OS 3 y versiones posteriores.
  • No se pueden crear credenciales en Wear OS.
  • No se admiten las credenciales de restablecimiento ni los flujos de acceso híbridos.
  • Solo se pueden volver a usar desde dispositivos móviles los proveedores de credenciales con integraciones de Wear OS.

Llaves de acceso en Wear OS

Se recomienda a los desarrolladores que implementen llaves de acceso en sus implementaciones de Credential Manager de Wear OS. Las llaves de acceso son el nuevo estándar de la industria para la autenticación del usuario final y ofrecen varios beneficios significativos para los usuarios.

Las llaves de acceso son más fáciles

  • Los usuarios pueden seleccionar una cuenta para acceder. No necesitan escribir un nombre de usuario.
  • Los usuarios pueden autenticarse con el bloqueo de pantalla del dispositivo.
  • Después de crear y registrar una llave de acceso, el usuario puede cambiar sin problemas a un dispositivo nuevo y usarlo de inmediato sin necesidad de volver a inscribirse.

Las llaves de acceso son más seguras

  • Los desarrolladores solo guardan una clave pública en el servidor en lugar de guardar una contraseña, lo que significa que hay mucho menos valor para que un actor malicioso hackee los servidores y mucho menos limpieza que hacer en caso de una vulneración.
  • Las llaves de acceso proporcionan protección resistente al phishing. Las llaves de acceso solo funcionan en los sitios web y las apps registrados. No se puede engañar a un usuario para que se autentique en un sitio engañoso porque el navegador o el SO controlan la verificación.
  • Las llaves de acceso reducen la necesidad de enviar SMS, lo que hace que la autenticación sea más rentable.

Implementa llaves de acceso

Incluye la configuración y la orientación para todos los tipos de implementación.

Configuración

  1. Establece el nivel de API objetivo en 35 en el archivo build.gradle del módulo de tu aplicación:

    android {
        defaultConfig {
            targetSdk(35)
        }
    }
    
  2. Agrega las siguientes líneas al archivo build.gradle de tu app o módulo, con la versión estable más reciente de la androidx.credentials versiones referencia.

    androidx.credentials:credentials:1.6.0
    androidx.credentials:credentials-play-services-auth:1.6.0
    

Métodos de autenticación integrados

Como Credential Manager es una API unificada, los pasos de implementación para Wear OS son los mismos que para cualquier otro tipo de dispositivo.

Usa las instrucciones para dispositivos móviles para comenzar y para implementar la compatibilidad con llaves de acceso y contraseñas.

Los pasos para agregar compatibilidad con Acceder con Google a Credential Manager están orientados al desarrollo para dispositivos móviles, pero los pasos son los mismos en Wear OS.

Ten en cuenta que, como no se pueden crear credenciales en Wear OS, no necesitas implementar los métodos de creación de credenciales que se mencionan en las instrucciones para dispositivos móviles.

Métodos de autenticación de copia de seguridad

Existen otros dos métodos de autenticación aceptables para las apps para Wear OS: OAuth 2.0 (cualquiera de las variantes) y el intercambio de tokens de autenticación para dispositivos móviles de la capa de datos. Si bien estos métodos no tienen puntos de integración en la API de Credential Manager, se pueden incluir en el flujo de UX de Credential Manager como alternativas en caso de que los usuarios descarten la pantalla de Credential Manager.

Para controlar la acción del usuario de descartar la pantalla de Credential Manager, detecta una NoCredentialException como parte de tu GetCredential lógica y navega a tu propia IU de autenticación personalizada.

try {
    val getCredentialResponse: GetCredentialResponse =
        credentialManager.getCredential(activity, createGetCredentialRequest())
    return authenticate(getCredentialResponse.credential)
} catch (_: GetCredentialCancellationException) {
    navigateToSecondaryAuthentication()
}

Luego, tu IU de autenticación personalizada puede proporcionar cualquiera de los otros métodos de autenticación aceptables que se describen en la guía de UX de acceso.

Intercambio de tokens de la capa de datos

La app complementaria para teléfonos puede transferir datos de autenticación de forma segura a la app para Wear OS con la API de Data Layer para wearables. Transfiere credenciales como mensajes o elementos de datos.

Por lo general, este tipo de autenticación no requiere ninguna acción por parte del usuario. Sin embargo, evita realizar la autenticación sin informarle al usuario que está accediendo. Puedes hacer esto con una pantalla que se pueda descartar y que muestre que la cuenta se está transfiriendo desde un dispositivo móvil.

Importante: Tu app para Wear OS debe ofrecer al menos un método más de autenticación, ya que esta opción solo funciona en relojes vinculados con Android cuando está instalada la app para dispositivos móviles correspondiente. Proporciona un método de autenticación alternativo para los usuarios que no tengan la app para dispositivos móviles correspondiente o cuyos dispositivos Wear OS estén vinculados con un dispositivo iOS.

Pasa tokens con la capa de datos de la app para dispositivos móviles, como se muestra en el siguiente ejemplo:

val token = "..." // Auth token to transmit to the Wear OS device.
val putDataReq: PutDataRequest = PutDataMapRequest.create("/auth").run {
    dataMap.putString("token", token)
    asPutDataRequest()
}
val putDataTask: Task<DataItem> = Wearable.getDataClient(this).putDataItem(putDataReq)

Detecta eventos de cambio de datos en la app para Wear OS, como se muestra en el siguiente ejemplo:

class AuthDataListenerService : WearableListenerService() {
    override fun onDataChanged(dataEvents: DataEventBuffer) {
        dataEvents.forEach { event ->
            if (event.type == DataEvent.TYPE_CHANGED) {
                val dataItemPath = event.dataItem.uri.path ?: ""

                if (dataItemPath.startsWith("/auth")) {
                    val token = DataMapItem.fromDataItem(event.dataItem)
                        .dataMap
                        .getString("token")
                    // Display an interstitial screen to notify the user that they're being signed
                    // in. Then, store the token and use it in network requests.
                    handleSignInSequence(token)
                }
            }
        }
    }

    /** placeholder sign in handler. */
    fun handleSignInSequence(token: String?) {}
}

Para obtener más información sobre el uso de la capa de datos de wearables, consulta Cómo enviar y sincronizar datos en Wear OS.

Usa OAuth 2.0

Wear OS admite dos flujos basados en OAuth 2.0, que se describen en las siguientes secciones:

  • Otorgamiento de código de autorización con clave de prueba para el intercambio de código (PKCE), como se define en RFC 7636
  • Otorgamiento de autorización de dispositivo (DAG), como se define en RFC 8628
Clave de prueba para el intercambio de código (PKCE)

Para usar la PKCE de manera efectiva, usa RemoteAuthClient. Luego, para realizar una solicitud de Auth a un proveedor de OAuth desde tu app para Wear OS, crea un OAuthRequest objeto. Este objeto consiste en una URL que dirige a tu extremo de OAuth para obtener un token y un CodeChallenge objeto.

A continuación, te mostramos un código de ejemplo para crear una solicitud de Auth:

val oauthRequest = OAuthRequest.Builder(context)
    .setAuthProviderUrl(uri)
    .setCodeChallenge(codeChallenge)
    .setClientId(CLIENT_ID)
    .build()

Una vez que compiles la solicitud de Auth, envíala a la app complementaria con el sendAuthorizationRequest() método.

RemoteAuthClient.create(context).sendAuthorizationRequest(
    request = oauthRequest,
    executor = { command -> command?.run() },
    clientCallback = object : RemoteAuthClient.Callback() {
        override fun onAuthorizationResponse(
            request: OAuthRequest,
            response: OAuthResponse
        ) {
            // Extract the token from the response, store it, and use it in requests.
            continuation.resume(parseCodeFromResponse(response))
        }
        override fun onAuthorizationError(request: OAuthRequest, errorCode: Int) {
            // Handle Errors
            continuation.resume(Result.failure(IOException("Authorization failed")))
        }
    }
)

Esta solicitud activará una llamada a la app complementaria, que luego presentará una IU de autorización en un navegador web en el teléfono celular del usuario. El proveedor de OAuth 2.0 autenticará al usuario y obtendrá su consentimiento para los permisos solicitados. La respuesta se envía a la URL de redireccionamiento que se genera automáticamente.

Luego de que la solicitud se procesa correctamente o falla, el servidor de OAuth 2.0 redirecciona a la URL especificada en la solicitud. Si el usuario aprueba la solicitud de acceso, la respuesta contendrá un código de autorización. Si no la aprueba, entonces esta contendrá un mensaje de error.

La respuesta lucirá como una cadena de consulta y se parecerá a uno de los ejemplos siguientes:

  https://wear.googleapis.com/3p_auth/com.your.package.name?code=xyz
  https://wear.googleapis-cn.com/3p_auth/com.your.package.name?code=xyz

Se cargará una página que dirigirá al usuario a la app complementaria, la cual verificará la URL de respuesta y la retransmitirá a tu app para Wear OS con la API de onAuthorizationResponse.

La app de reloj puede intercambiar el código de autorización por un token de acceso.

Otorgamiento de autorización de dispositivo

Cuando se usa el otorgamiento de autorización de dispositivo, el usuario abre el URI de verificación en otro dispositivo. Luego, el servidor de autorización les solicita aprobar o rechazar la solicitud.

Con el objetivo de facilitar este proceso, usa un RemoteActivityHelper para abrir una página web en el dispositivo móvil vinculado del usuario, como se muestra en el siguiente ejemplo:

// Request access from the authorization server and receive Device Authorization Response.
private fun verifyDeviceAuthGrant(verificationUri: String) {
    RemoteActivityHelper(context).startRemoteActivity(
        Intent(Intent.ACTION_VIEW).apply {
            addCategory(Intent.CATEGORY_BROWSABLE)
            data = Uri.parse(verificationUri)
        },
        null
    )
}

Si tienes una app para iOS, usa vínculos universales e intercepta este intent en tu app, en lugar de depender del navegador para autorizar el token.