Tutorial: Adicionar redefinição de senha de autoatendimento

Este tutorial demonstra como permitir que os usuários alterem ou redefina suas senhas, sem envolvimento de administrador ou suporte técnico.

Neste tutorial, irá aprender a:

  • Adicione o fluxo de redefinição de senha de autoatendimento (SSPR).
  • Adicione a interface do usuário (UI) necessária para SSPR ao seu aplicativo.
  • Manipule erros.

Pré-requisitos

  • Conclua as etapas em Entrar usuários em um aplicativo móvel Android nativo de exemplo. Este artigo mostra como executar um exemplo de Android que você configura usando as configurações do locatário.
  • Habilite a redefinição de senha de autoatendimento. Este artigo permite que você habilite o método de autenticação de senha única de email para todos os usuários em seu locatário, que é um requisito para SSPR.
  • Tutorial: Prepare seu aplicativo Android para autenticação nativa.

Adicionar fluxo de redefinição de senha de autoatendimento

Para adicionar o fluxo SSPR ao seu aplicativo Android, você precisa de uma interface de usuário de redefinição de senha:

  • Um campo de texto de entrada para coletar o endereço de e-mail do usuário (nome de usuário).
  • Um campo de texto de entrada para coletar uma senha única.
  • Um campo de texto de entrada para coletar nova senha.

Quando os usuários esquecem suas senhas, eles precisam de um formulário para inserir seus nomes de usuário (endereços de e-mail) para iniciar o fluxo de redefinição de senha. O usuário seleciona o botão ou link Esquecer senha .

Iniciar fluxo de redefinição de senha

Para lidar com a solicitação quando o usuário seleciona o botão ou link Esquecer senha , use o método do SDK do resetPassword(username) Android, conforme mostrado no trecho de código a seguir:

 private fun forgetPassword() { 
  CoroutineScope(Dispatchers.Main).launch { 
      try { 
        val resetPasswordResult = authClient.resetPassword( 
              username = emailAddress 
          ) 

         when (resetPasswordResult) { 
             is ResetPasswordStartResult.CodeRequired -> { 
                 // The implementation of submiteCode() please see below. 
                 submitCode(resetPasswordResult.nextState) 
             } 
              is ResetPasswordError -> {
                  // Handle errors
                  handleResetPasswordError(resetPasswordResult)
              }
         } 
     } catch (exception: MsalException) { 
          // Handle exception 
      } 
  } 
 } 
  • resetPassword(username) O método inicia o fluxo de redefinição de senha e uma senha única de e-mail é enviada para o endereço de e-mail do usuário para verificação.

  • O resultado do retorno de resetPassword(username) é ou ResetPasswordErrorResetPasswordStartResult.CodeRequired .

  • Se resetPasswordResult is ResetPasswordStartResult.CodeRequiredo , o aplicativo precisa coletar a senha única de e-mail do usuário e enviá-la conforme mostrado em Enviar senha única de e-mail.

  • Se resetPasswordResult is ResetPasswordErroro SDK do Android fornecer métodos utilitários para permitir que você analise ainda mais os erros específicos: - isUserNotFound() - isBrowserRequired()

  • Esses erros indicam que a operação anterior não foi bem-sucedida e, portanto, uma referência a um novo estado não está disponível. Manipule esses erros conforme mostrado na seção Manipular erros .

Enviar código de acesso único por e-mail

Seu aplicativo coleta a senha única de e-mail do usuário. Para enviar a senha única de e-mail, use o seguinte trecho de código:

private suspend fun submitCode(currentState: ResetPasswordCodeRequiredState) { 
    val code = binding.codeText.text.toString() 
    val submitCodeResult = currentState.submitCode(code) 

    when (submitCodeResult) { 
        is ResetPasswordSubmitCodeResult.PasswordRequired -> { 
            // Handle success
            resetPassword(submitCodeResult.nextState) 
        } 
         is SubmitCodeError -> {
             // Handle errors
             handleSubmitCodeError(actionResult)
         }
    } 
} 
  • O resultado de retorno da submitCode() ação é ou ResetPasswordSubmitCodeResult.PasswordRequired SubmitCodeError.

  • Se submitCodeResult is ResetPasswordSubmitCodeResult.PasswordRequired o aplicativo precisar coletar uma nova senha do usuário e enviá-la, conforme mostrado em Enviar uma nova senha.

  • Se o usuário não receber a senha única do e-mail em seu e-mail, o aplicativo poderá reenviar a senha única do e-mail. Use o seguinte trecho de código para reenviar uma nova senha única de e-mail:

    private fun resendCode() { 
         clearCode() 
    
         val currentState = ResetPasswordCodeRequiredState 
    
         CoroutineScope(Dispatchers.Main).launch { 
             val resendCodeResult = currentState.resendCode() 
    
             when (resendCodeResult) { 
                 is ResetPasswordResendCodeResult.Success -> { 
                     // Handle code resent success
                 } 
                 is ResendCodeError -> {
                      // Handle ResendCodeError errors
                  }
             } 
         } 
    } 
    
    • O resultado de retorno da resendCode() ação é ou ResetPasswordResendCodeResult.Success ResendCodeError.

    • ResendCodeError é um erro inesperado para o SDK. Esse erro indica que a operação anterior não foi bem-sucedida, portanto, uma referência a um novo estado não está disponível.

  • Se submitCodeResult is SubmitCodeErroro SDK do Android fornecer métodos utilitários para permitir que você analise melhor os erros específicos:

    • isInvalidCode()
    • isBrowserRequired()

    Esses erros indicam que a operação anterior não foi bem-sucedida e, portanto, uma referência a um novo estado não está disponível. Manipule esses erros conforme mostrado na seção Manipular erros .

Enviar uma nova senha

Depois de verificar o e-mail do usuário, você precisa coletar uma nova senha do usuário e enviá-la. A senha que o aplicativo coleta do usuário precisa atender às políticas de senha do Microsoft Entra. Use o seguinte trecho de código:

private suspend fun resetPassword(currentState: ResetPasswordPasswordRequiredState) { 
    val password = binding.passwordText.text.toString() 

    val submitPasswordResult = currentState.submitPassword(password) 

    when (submitPasswordResult) { 
        is ResetPasswordResult.Complete -> { 
            // Handle reset password complete. 
        } 
        is ResetPasswordSubmitPasswordError -> {
            // Handle errors
            handleSubmitPasswordError(actionResult)
        }
    } 
} 
  • O resultado de retorno da submitPassword() ação é ou ResetPasswordResult.Complete ResetPasswordSubmitPasswordError.

  • ResetPasswordResult.Complete indica um fluxo de redefinição de senha bem-sucedido.

  • Se submitPasswordResult is ResetPasswordSubmitPasswordErroro SDK fornecer métodos utilitários para analisar melhor o tipo específico de erro retornado: - isInvalidPassword() - isPasswordResetFailed()

    Esses erros indicam que a operação anterior não foi bem-sucedida e, portanto, uma referência a um novo estado não está disponível. Manipule esses erros conforme mostrado na seção Manipular erros .

Entrada automática após redefinição de senha

Após um fluxo de redefinição de senha bem-sucedido, você pode entrar automaticamente em seus usuários sem iniciar um novo fluxo de entrada.

O ResetPasswordResult.Complete objeto de retorno SignInContinuationState . O SignInContinuationState fornece acesso ao signIn() método.

Para entrar automaticamente nos usuários após uma redefinição de senha, use o seguinte trecho de código:

 private suspend fun resetPassword(currentState: ResetPasswordPasswordRequiredState) { 
     val submitPasswordResult = currentState.submitPassword(password) 
 
     when (submitPasswordResult) { 
         is ResetPasswordResult.Complete -> { 
             signInAfterPasswordReset(nextState = actionResult.nextState)
         } 
     } 
 } 
 
 private suspend fun signInAfterPasswordReset(nextState: SignInContinuationState) {
      val currentState = nextState
      val actionResult = currentState.signIn()
      when (actionResult) {
          is SignInResult.Complete -> {
              fetchTokens(accountState = actionResult.resultValue)
          }
          else {
              // Handle unexpected error
          }
      }
  }
 
  private suspend fun fetchTokens(accountState: AccountState) {
      val accessTokenResult = accountState.getAccessToken()
      if (accessTokenResult is GetAccessTokenResult.Complete) {
          val accessToken =  accessTokenResult.resultValue.accessToken
          val idToken = accountState.getIdToken()
      }
 }

Para recuperar declarações de token de ID após o login, use as etapas em Declarações de token de ID de leitura.

Manipular erros de redefinição de senha

Alguns erros esperados podem ocorrer. Por exemplo, o usuário pode tentar redefinir a senha com um e-mail inexistente ou fornecer uma senha que não atenda aos requisitos de senha.

Quando ocorrerem erros, dê aos usuários uma dica sobre os erros.

Esses erros podem acontecer no início do fluxo de redefinição de senha ou no envio de senha única de e-mail ou no envio de senha.

Manipular erro de redefinição de senha de início

Para manipular o erro causado pela redefinição de senha de início, use o seguinte trecho de código:

private fun handleResetPasswordError(error: ResetPasswordError) {
    when {
        error.isUserNotFound() -> {
            // Display error
        }
        else -> {
            // Unexpected error
        }
    }
}

Lidar com o erro de senha única de envio de e-mail

Para lidar com o erro causado pelo envio de senha única de e-mail, use o seguinte trecho de código:

private fun handleSubmitCodeError(error: SubmitCodeError) {
    when {
        error.isInvalidCode() -> {
            // Display error
        }
        else -> {
            // Unexpected error
        }
    }
}

Manipular erro de senha de envio

Para manipular o erro causado pelo envio de senha, use o seguinte trecho de código:

private fun handleSubmitPasswordError(error: ResetPasswordSubmitPasswordError) {
    when {
        error.isInvalidPassword() || error.isPasswordResetFailed()
        -> {
            // Display error
        }
        else -> {
            // Unexpected error
        }
    }
}

Próximos passos

Tutorial: Suporte a fallback da Web no aplicativo Android