Compartir vía


Tutorial: inicio de sesión de los usuarios en la aplicación móvil Android (Kotlin)

Este es el tercer tutorial de la serie de tutoriales que le guiará en el inicio de sesión de los usuarios usando Id. externa de Microsoft Entra.

En este tutorial, hará lo siguiente:

  • Inicio de sesión de los usuarios
  • Cerrar la sesión del usuario

Requisitos previos

Tutorial: preparación de la aplicación Android para la autenticación.

Inicio de sesión de los usuarios

Tiene dos opciones principales para el inicio de sesión de usuarios mediante la Biblioteca de autenticación de Microsoft (MSAL) para Android: adquirir tokens de forma interactiva o silenciosa.

  1. Para iniciar sesión de forma interactiva, use el código siguiente:

        private fun acquireTokenInteractively() {
        binding.txtLog.text = ""
    
        if (account != null) {
            Toast.makeText(this, "An account is already signed in.", Toast.LENGTH_SHORT).show()
            return
        }
    
        /* Extracts a scope array from text, i.e. from "User.Read User.ReadWrite" to ["user.read", "user.readwrite"] */
        val scopes = scopes.lowercase().split(" ")
        val parameters = AcquireTokenParameters.Builder()
            .startAuthorizationFromActivity(this@MainActivity)
            .withScopes(scopes)
            .withCallback(getAuthInteractiveCallback())
            .build()
    
        authClient.acquireToken(parameters)
    }
    

    El código inicia el proceso de adquisición de un token de forma interactiva con la ayuda de MSAL para Android. Primero borra el campo de registro de texto. A continuación, comprueba si ya hay una cuenta que ha iniciado sesión, si es así, muestra un mensaje del sistema que indica que ya hay una cuenta que ha iniciado sesión y devuelve.

    A continuación, extrae ámbitos de la entrada de texto y los convierte en minúsculas antes de dividirlos en una matriz. Con estos ámbitos, crea parámetros para adquirir un token, incluido el inicio del proceso de autorización desde la actividad actual y la especificación de una devolución de llamada. Por último, llama a acquireToken() en el cliente de autenticación con los parámetros construidos para iniciar el proceso de adquisición de tokens.

    En el código, donde especificamos nuestra devolución de llamada, usamos una función denominada getAuthInteractiveCallback(). La función debe tener el código siguiente:

    private fun getAuthInteractiveCallback(): AuthenticationCallback {
        return object : AuthenticationCallback {
    
            override fun onSuccess(authenticationResult: IAuthenticationResult) {
                /* Successfully got a token, use it to call a protected resource - Web API */
                Log.d(TAG, "Successfully authenticated")
                Log.d(TAG, "ID Token: " + authenticationResult.account.claims?.get("id_token"))
                Log.d(TAG, "Claims: " + authenticationResult.account.claims
    
                /* Reload account asynchronously to get the up-to-date list. */
                CoroutineScope(Dispatchers.Main).launch {
                    accessToken = authenticationResult.accessToken
                    getAccount()
    
                    binding.txtLog.text = getString(R.string.log_token_interactive) +  accessToken
                }
            }
    
            override fun onError(exception: MsalException) {
                /* Failed to acquireToken */
                Log.d(TAG, "Authentication failed: $exception")
    
                accessToken = null
                binding.txtLog.text = getString(R.string.exception_authentication) + exception
    
                if (exception is MsalClientException) {
                    /* Exception inside MSAL, more info inside MsalError.java */
                } else if (exception is MsalServiceException) {
                    /* Exception when communicating with the STS, likely config issue */
                }
            }
    
            override fun onCancel() {
                /* User canceled the authentication */
                Log.d(TAG, "User cancelled login.");
            }
        }
    }
    

    El fragmento de código define una función, getAuthInteractiveCallback, que devuelve una instancia de AuthenticationCallback. Dentro de esta función, se crea una clase anónima que implementa la interfaz AuthenticationCallback.

    Cuando la autenticación se realiza correctamente (onSuccess), registra la autenticación correcta, recupera el token de id. y las notificaciones, actualiza el token de acceso de forma asincrónica mediante CoroutineScope, y actualiza la interfaz de usuario con el nuevo token de acceso. El código recupera el token de id. de authenticationResult y lo registra. Las notificaciones del token contienen información sobre el usuario, como su nombre, correo electrónico u otra información de perfil. Puede recuperar las notificaciones asociadas a la cuenta actual accediendo a authenticationResult.account.claims.

    Si hay un error de autenticación (onError), registra el error, borra el token de acceso, actualiza la interfaz de usuario con el mensaje de error y proporciona un control más específico para MsalClientException y MsalServiceException. Si el usuario cancela la autenticación (onCancel), registra la cancelación.

    Asegúrese de incluir las instrucciones import. Android Studio debe incluir automáticamente las instrucciones import.

  2. Para iniciar sesión de forma silenciosa, use el código siguiente:

        private fun acquireTokenSilently() {
        binding.txtLog.text = ""
    
        if (account == null) {
            Toast.makeText(this, "No account available", Toast.LENGTH_SHORT).show()
            return
        }
    
        /* Extracts a scope array from text, i.e. from "User.Read User.ReadWrite" to ["user.read", "user.readwrite"] */
        val scopes = scopes.lowercase().split(" ")
        val parameters = AcquireTokenSilentParameters.Builder()
            .forAccount(account)
            .fromAuthority(account!!.authority)
            .withScopes(scopes)
            .forceRefresh(false)
            .withCallback(getAuthSilentCallback())
            .build()
    
        authClient.acquireTokenSilentAsync(parameters)
    }
    

    El código inicia el proceso de adquisición de un token de forma silenciosa. Primero borra el registro de texto. A continuación, comprueba si hay una cuenta disponible; si no es así, muestra un mensaje del sistema que indica esto y se cierra. A continuación, extrae ámbitos de la entrada de texto, los convierte en minúsculas y los divide en una matriz.

    Con estos ámbitos, crea parámetros para adquirir un token de forma silenciosa, especificando la cuenta, la autoridad, los ámbitos y la devolución de llamada. Por último, se desencadena acquireTokenSilentAsync() de forma asincrónica en el cliente de autenticación con los parámetros construidos, iniciando el proceso de adquisición silenciosa de tokens.

    En el código, donde especificamos nuestra devolución de llamada, usamos una función denominada getAuthSilentCallback(). La función debe tener el código siguiente:

    private fun getAuthSilentCallback(): SilentAuthenticationCallback {
        return object : SilentAuthenticationCallback {
            override fun onSuccess(authenticationResult: IAuthenticationResult?) {
                Log.d(TAG, "Successfully authenticated")
    
                /* Display Access Token */
                accessToken = authenticationResult?.accessToken
                binding.txtLog.text = getString(R.string.log_token_silent) + accessToken
            }
    
            override fun onError(exception: MsalException?) {
                /* Failed to acquireToken */
                Log.d(TAG, "Authentication failed: $exception")
    
                accessToken = null
                binding.txtLog.text = getString(R.string.exception_authentication) + exception
    
                when (exception) {
                    is MsalClientException -> {
                        /* Exception inside MSAL, more info inside MsalError.java */
                    }
                    is MsalServiceException -> {
                        /* Exception when communicating with the STS, likely config issue */
                    }
                    is MsalUiRequiredException -> {
                        /* Tokens expired or no session, retry with interactive */
                    }
                }
            }
    
        }
    }
    

    El código define una devolución de llamada para la autenticación silenciosa. Implementa la interfaz SilentAuthenticationCallback, reemplazando dos métodos. En el método onSuccess, registra la autenticación correcta y muestra el token de acceso.

    En el método onError, registra un error de autenticación, controla diferentes tipos de excepciones, como MsalClientException y MsalServiceException, y sugiere un nuevo intento con la autenticación interactiva si es necesario.

    Asegúrese de incluir las instrucciones import. Android Studio debe incluir automáticamente las instrucciones import.

Cerrar sesión

Para cerrar la sesión de un usuario de la aplicación Android (Kotlin) mediante MSAL para Android, use el código siguiente:

private fun removeAccount() {
    binding.userName.text = ""
    binding.txtLog.text = ""

    authClient.signOut(signOutCallback())
}

El código quita una cuenta de la aplicación. Borra el nombre de usuario mostrado y el registro de texto. A continuación, desencadena el proceso de cierre de sesión mediante el cliente de autenticación, especificando una devolución de llamada de cierre de sesión para controlar la finalización de la operación de cierre de sesión.

En el código, donde especificamos nuestra devolución de llamada, usamos una función denominada signOutCallback(). La función debe tener el código siguiente:

private fun signOutCallback(): ISingleAccountPublicClientApplication.SignOutCallback {
    return object : ISingleAccountPublicClientApplication.SignOutCallback {
        override fun onSignOut() {
            account = null
            updateUI(account)
        }

        override fun onError(exception: MsalException) {
            binding.txtLog.text = getString(R.string.exception_remove_account) + exception
        }
    }
}

El código define una devolución de llamada de cierre de sesión para una sola cuenta en la aplicación cliente pública. Implementa la interfaz ISingleAccountPublicClientApplication.SignOutCallback, reemplazando dos métodos.

En el método onSignOut, anula la cuenta actual y actualiza la interfaz de usuario en consecuencia. En el método onError, registra los errores que se producen durante el proceso de cierre de sesión y actualiza el registro de texto con el mensaje de excepción correspondiente.

Asegúrese de incluir las instrucciones import. Android Studio debe incluir automáticamente las instrucciones import.

Pasos siguientes

Tutorial: llamada a una API web protegida en la aplicación Android (Kotlin).