チュートリアル: セルフサービス パスワード リセットを追加する
このチュートリアルでは、管理者やヘルプ デスクが関与することなく、ユーザーが自分のパスワードを変更またはリセットできるようにするための方法を示します。
このチュートリアルでは、次の作業を行う方法について説明します。
- セルフサービス パスワード リセット (SSPR) フローを追加します。
- SSPR に必要なユーザー インターフェイス (UI) をアプリに追加します。
- エラーを処理します。
前提条件
- サンプルのネイティブ Android モバイル アプリケーションでユーザーをサインインさせるに関する記事の手順を完了します。 この記事では、テナント設定を使用して構成するサンプル Android を実行する方法について説明します。
- セルフサービス パスワード リセットを有効にする。. この記事では、SSPR の要件である、テナント内のすべてのユーザーに対してメールのワンタイム パスコードの認証方法を有効にすることができます。
- チュートリアル: ネイティブ認証用に Android アプリを準備する。
セルフサービス パスワード リセットのフローを追加する
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.Complete
は SignInContinuationState
オブジェクトを返します。 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
}
}
}