Compartilhar via


Tutorial: Conectar usuários no aplicativo móvel Android (Kotlin)

Este é o terceiro tutorial da série de tutoriais que orienta você sobre como conectar usuários usando a ID externa do Microsoft Entra.

Neste tutorial, você aprenderá a:

  • Conectar usuário
  • Desconectar usuário

Pré-requisitos

Tutorial: Preparar seu aplicativo Android para autenticação.

Conectar usuário

Você tem duas opções básicas para conectar usuários com a MSAL (Biblioteca de Autenticação da Microsoft) para Android: adquirir tokens de forma interativa ou silenciosa.

  1. Para conectar o usuário de forma interativa, use o seguinte código:

        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)
    }
    

    O código inicia o processo de aquisição de um token de forma interativa usando a MSAL para Android. Primeiro, ele limpa o campo de log de texto. Em seguida, ele verifica se já há uma conta conectada. Nesse caso, uma mensagem do sistema é exibida indicando que uma conta já está conectada e retorna.

    Depois, ele extrai escopos da entrada de texto e os converte em letras minúsculas antes de dividi-los em uma matriz. Usando esses escopos, ele cria parâmetros para adquirir um token, incluindo iniciar o processo de autorização da atividade atual e especificar um retorno de chamada. Por fim, ele chama acquireToken() no cliente de autenticação com os parâmetros construídos para iniciar o processo de aquisição de token.

    No código em que especificamos nosso retorno de chamada, usamos uma função chamada getAuthInteractiveCallback(). A função deve ter o seguinte código:

    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.");
            }
        }
    }
    

    O snippet de código define uma função getAuthInteractiveCallback que retorna uma instância de AuthenticationCallback. Nessa função, uma classe anônima que implementa a interface AuthenticationCallback é criada.

    Quando a autenticação é bem-sucedida (onSuccess), ela registra a autenticação bem-sucedida, recupera o token de ID e declarações, atualiza o token de acesso de forma assíncrona usando CoroutineScope e atualiza a interface do usuário com o novo token de acesso. O código recupera o token de ID do authenticationResult e registra-o. As declarações no token contêm informações sobre o usuário, como nome, email ou outras informações de perfil. É possível recuperar as declarações associadas à conta atual acessando authenticationResult.account.claims.

    Se houver um erro de autenticação (onError), ele vai registrar o erro, limpar o token de acesso, atualizar a interface do usuário com a mensagem de erro e fornecer um tratamento mais específico para MsalClientException e MsalServiceException. Se o usuário cancelar a autenticação (onCancel), ele registrará o cancelamento.

    Certifique-se de incluir as instruções de importação. O Android Studio deve incluir as instruções de importação para você automaticamente.

  2. Para conectar o usuário silenciosamente, use o seguinte código:

        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)
    }
    

    O código inicia o processo de aquisição silenciosa de um token. Primeiro, ele limpa o log de texto. Em seguida, ele verifica se há uma conta disponível; caso contrário, ele exibe uma mensagem do sistema indicando a ausência de uma conta e sai. Depois, ele extrai escopos da entrada de texto, converte-os em letras minúsculas e os divide em uma matriz.

    Usando esses escopos, ele constrói parâmetros para adquirir um token silenciosamente, especificando a conta, a autoridade, os escopos e o retorno de chamada. Por fim, ele dispara acquireTokenSilentAsync() de forma assíncrona no cliente de autenticação com os parâmetros construídos, iniciando o processo de aquisição silenciosa do token.

    No código em que especificamos nosso retorno de chamada, usamos uma função chamada getAuthSilentCallback(). A função deve ter o seguinte código:

    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 */
                    }
                }
            }
    
        }
    }
    

    O código define um retorno de chamada para autenticação silenciosa. Ele implementa a interface SilentAuthenticationCallback, substituindo dois métodos. No método onSuccess, ele registra a autenticação bem-sucedida e exibe o token de acesso.

    No método onError, ele registra a falha de autenticação, lida com diferentes tipos de exceções, como MsalClientException e MsalServiceException, e sugere uma nova tentativa com a autenticação interativa, se necessário.

    Certifique-se de incluir as instruções de importação. O Android Studio deve incluir as instruções de importação para você automaticamente.

Sair

Para desconectar um usuário do aplicativo Android (Kotlin) usando a MSAL para Android, use o seguinte código:

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

    authClient.signOut(signOutCallback())
}

O código remove uma conta do aplicativo. Ele limpa o nome de usuário exibido e o log de texto. Em seguida, ele dispara o processo de saída com o cliente de autenticação, especificando um retorno de chamada de saída para lidar com a conclusão da operação de saída.

No código em que especificamos nosso retorno de chamada, usamos uma função chamada signOutCallback(). A função deve ter o seguinte código:

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
        }
    }
}

O código define um retorno de chamada de saída para uma única conta no aplicativo cliente público. Ele implementa a interface ISingleAccountPublicClientApplication.SignOutCallback, substituindo dois métodos.

No método onSignOut, ele anula a conta atual e atualiza a interface do usuário adequadamente. No método onError, ele registra todos os erros que ocorrem durante o processo de saída e atualiza o log de texto com a mensagem de exceção correspondente.

Certifique-se de incluir as instruções de importação. O Android Studio deve incluir as instruções de importação para você automaticamente.

Próximas etapas

Tutorial: Chamar uma API Web protegida no aplicativo Android (Kotlin).