次の方法で共有


チュートリアル: セルフサービス パスワード リセットを追加する

このチュートリアルでは、管理者やヘルプ デスクが関与することなく、ユーザーが自分のパスワードを変更またはリセットできるようにするための方法を示します。

このチュートリアルでは、次の作業を行う方法について説明します。

  • セルフサービス パスワード リセット (SSPR) フローを追加します。
  • SSPR に必要なユーザー インターフェイス (UI) をアプリに追加します。
  • エラーを処理します。

前提条件

セルフサービス パスワード リセットのフローを追加する

Android アプリケーションに SSPR フローを追加するには、次のパスワードのリセットのユーザー インターフェイスが必要です。

  • ユーザーのメール アドレス (ユーザー名) を収集するための入力テキスト フィールド。
  • ワンタイム パスコードを収集するための入力テキスト フィールド。
  • 新しいパスワードを収集するための入力テキスト フィールド。

ユーザーがパスワードを忘れた場合、パスワードのリセット フローを開始するには、ユーザー名 (メール アドレス) を入力するフォームが必要になります。 ユーザーが [パスワードを忘れた場合] ボタンまたはリンクを選択します。

パスワードのリセット フローを開始する

ユーザーが [パスワードを忘れた場合] ボタンまたはリンクを選択したときの要求を処理するには、次のコード スニペットに示すように Android SDK の resetPassword(username) メソッドを使用します。

 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) メソッドによってパスワードのリセット フローが開始され、確認のためにメールのワンタイム パスコードがユーザーのメール アドレスに送信されます。

  • resetPassword(username) 結果の戻り値は、ResetPasswordStartResult.CodeRequired または ResetPasswordError のどちらかです。

  • resetPasswordResult is ResetPasswordStartResult.CodeRequired の場合、アプリでは、ユーザーからメールのワンタイム パスコードを収集して、「メールのワンタイム パスコードを送信する」に示すように送信する必要があります。

  • resetPasswordResult is ResetPasswordError の場合、Android SDK には、特定のエラーをさらに分析できるようにするユーティリティ メソッド isUserNotFound() - isBrowserRequired() が用意されています

  • これらのエラーは、前の操作が失敗したため、新しい状態への参照が使用できないことを示します。 エラーの処理に関するセクションに示すように、これらのエラーを処理します。

メールのワンタイム パスコードを送信する

アプリでは、ユーザーからメールのワンタイム パスコードを収集します。 メールのワンタイム パスコードを送信するには、次のコード スニペットを使用します。

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)
         }
    } 
} 
  • submitCode() アクションの結果の戻り値は、ResetPasswordSubmitCodeResult.PasswordRequired または SubmitCodeError のどちらかです。

  • submitCodeResult is ResetPasswordSubmitCodeResult.PasswordRequired の場合、アプリではユーザーから新しいパスワードを収集し、「新しいパスワードを送信する」に示すように送信する必要があります。

  • ユーザーがメールでメールのワンタイム パスコードを受信しなかった場合、アプリでメールのワンタイム パスコードを再送信できます。 新しいメールのワンタイム パスコードを再送信するには、次のコード スニペットを使用します。

    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
                  }
             } 
         } 
    } 
    
    • resendCode() アクションの結果の戻り値は、ResetPasswordResendCodeResult.Success または ResendCodeError のどちらかです。

    • ResendCodeError は SDK の予期しないエラーです。 このエラーは、前の操作が失敗したため、新しい状態への参照が使用できないことを示します。

  • submitCodeResult is SubmitCodeError の場合、Android SDK には、特定のエラーをさらに分析できるようにするユーティリティ メソッドが用意されています。

    • isInvalidCode()
    • isBrowserRequired()

    これらのエラーは、前の操作が失敗したため、新しい状態への参照が使用できないことを示します。 エラーの処理に関するセクションに示すように、これらのエラーを処理します。

新しいパスワードを送信する

ユーザーのメール アドレスを確認したら、ユーザーから新しいパスワードを収集して送信する必要があります。 アプリによってユーザーから収集されるパスワードは、Microsoft Entra のパスワード ポリシーを満たす必要があります。 次のようなコード スニペットを使用します。

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)
        }
    } 
} 
  • submitPassword() アクションの結果の戻り値は、ResetPasswordResult.Complete または ResetPasswordSubmitPasswordError のどちらかです。

  • ResetPasswordResult.Complete は、成功したパスワードのリセット フローを示します。

  • submitPasswordResult is ResetPasswordSubmitPasswordError の場合、SDK には、返される特定の種類のエラーをさらに分析するためのユーティリティ メソッド isInvalidPassword() - isPasswordResetFailed() が用意されています

    これらのエラーは、前の操作が失敗したため、新しい状態への参照が使用できないことを示します。 エラーの処理に関するセクションに示すように、これらのエラーを処理します。

パスワードのリセット後の自動サインイン

パスワードのリセット フローが正常に完了したら、新しいサインイン フローを開始せずにユーザーを自動的にサインインさせることができます。

ResetPasswordResult.CompleteSignInContinuationState オブジェクトを返します。 SignInContinuationState では signIn() メソッドへのアクセスを提供します。

パスワードのリセット後にユーザーを自動的にサインインさせるには、次のコード スニペットを使用します。

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

サインイン後に ID トークン要求を取得するには、「ID トークン要求を読み取る」の手順を使用します。

パスワードのリセット エラーを処理する

想定内のエラーがいくつか発生する場合があります。 たとえば、ユーザーが存在しないメールでパスワードをリセットしようとしたり、パスワード要件を満たしていないパスワードを入力したりする場合があります。

エラーが発生した場合は、ユーザーにエラーのヒントを提供します。

これらのエラーは、パスワードのリセット フローの開始時、メールのワンタイム パスコードの送信時、またはパスワードの送信時に発生する可能性があります。

パスワードのリセットの開始エラーを処理する

パスワードのリセットの開始に起因するエラーを処理するには、次のコード スニペットを使用します。

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

メールのワンタイム パスコードの送信エラーを処理する

メールのワンタイム パスコードの送信によって発生するエラーを処理するには、次のコード スニペットを使用します。

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

パスワード送信エラーを処理する

パスワードの送信によって発生するエラーを処理するには、次のコード スニペットを使用します。

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

次のステップ

チュートリアル: Android アプリでの Web フォールバックのサポート