Поделиться через


Руководство. Добавление входа в приложение Android с помощью собственной проверки подлинности

В этом руководстве показано, как войти и выйти пользователя с помощью однократного секретного кода или пароля электронной почты в мобильном приложении Android с помощью собственной проверки подлинности.

В этом руководстве описано следующее:

  • Войдите в систему, используя одноразовый секретный код электронной почты или имя пользователя (электронная почта) и пароль.
  • Выйдите из пользователя.
  • Обработка ошибки входа

Необходимые компоненты

Вход пользователя

Чтобы войти пользователя с помощью однократного секретного кода, соберите сообщение электронной почты и отправьте сообщение электронной почты, содержащее одноразовый секретный код для пользователя, чтобы проверить их электронную почту. Когда пользователь вводит действительный одноразовый секретный код, приложение войдет в систему.

Чтобы войти пользователя с помощью имени пользователя (электронной почты) и пароля, соберите сообщение электронной почты и пароль от пользователя. Если имя пользователя и пароль действительны, приложение войдите в систему пользователя.

Чтобы войти в систему, необходимо выполнить следующие действия.

  1. Создайте пользовательский интерфейс для:

    • Сбор сообщения электронной почты от пользователя. Добавьте проверку в входные данные, чтобы убедиться, что пользователь вводит допустимый адрес электронной почты.
    • Соберите пароль при входе с помощью имени пользователя (электронной почты) и пароля.
    • Соберите одноразовый секретный код электронной почты от пользователя, если вы войдите в систему с помощью однократного секретного кода электронной почты.
    • Повторно отправьте одноразовый секретный код (рекомендуется), если вы войдите в систему с помощью однократного секретного кода электронной почты.
  2. В пользовательском интерфейсе добавьте кнопку, событие выбора которой запускает вход, как показано в следующем фрагменте кода:

     CoroutineScope(Dispatchers.Main).launch {
         val parameters = NativeAuthSignInParameters(username = email)
         // Assign 'password' param if you sign in with username (email) and password
         // parameters.password = password
         val actionResult: SignInResult = authClient.signIn(parameters)
    
         if (actionResult is SignInResult.CodeRequired) {
             val nextState = actionResult.nextState
             val submitCodeActionResult = nextState.submitCode(
                 code = code
             )
             if (submitCodeActionResult is SignInResult.Complete) {
                 // Handle sign in success
                 val accountState = submitCodeActionResult.resultValue
    
                 val getAccessTokenParameters = NativeAuthGetAccessTokenParameters()
                 val accessTokenResult = accountState.getAccessToken(getAccessTokenParameters)
    
                 if (accessTokenResult is GetAccessTokenResult.Complete) {
                     val accessToken = accessTokenResult.resultValue.accessToken
                     val idToken = accountState.getIdToken()
                 }
             }
         }
     }
    

    Если пользователю не требуется отправить секретный код, например, когда пользователь входит с помощью электронной почты и пароля, используйте следующий фрагмент кода:

    CoroutineScope(Dispatchers.Main).launch {
        val parameters = NativeAuthSignInParameters(username = email)
        parameters.password = password
        val actionResult: SignInResult = authClient.signIn(parameters)
    
        if (actionResult is SignInResult.Complete) -> {
            // Handle sign in success
            val accountState = actionResult.resultValue
    
            val getAccessTokenParameters = NativeAuthGetAccessTokenParameters()
            val accessTokenResult = accountState.getAccessToken(getAccessTokenParameters)
    
            if (accessTokenResult is GetAccessTokenResult.Complete) {
                val accessToken = accessTokenResult.resultValue.accessToken
                val idToken = accountState.getIdToken()
            }
        }
    }
    
    • Чтобы запустить поток входа, используйте метод signIn(parameters) пакета SDK.
    • Экземпляр класса NativeAuthSignInParameters, содержащий username, представляющий собой адрес электронной почты, который вы собираете у пользователя.
    • Если метод входа — имя пользователя (электронная почта) и пароль, параметр метода — это пароль, password который вы собираете от пользователя.
    • В большинстве распространённых случаев signIn(parameters) возвращает результат SignInResult.CodeRequired, что означает, что приложение должно передать одноразовый код доступа, отправленный на адрес электронной почты пользователя.
    • Объект SignInResult.CodeRequired содержит новую ссылку на состояние, которую можно получить.actionResult.nextState
    • Новое состояние дает нам доступ к двум новым методам:
      • submitCode() отправляет одноразовый секретный код электронной почты, который приложение собирает от пользователя.
      • resendCode() повторно отправляет секретный код электронной почты, если пользователь не получает код.

Обработка ошибок входа

Во время входа не все действия выполняются успешно. Например, пользователь может попытаться войти с помощью адреса электронной почты, который не существует или отправить недопустимый код.

Обработка ошибок запуска входа

Чтобы обрабатывать ошибки в методе signIn(parameters), используйте следующий фрагмент кода:

 val parameters = NativeAuthSignInParameters(username = email)
 // Assign 'password' param if you sign in with username (email) and password
 // parameters.password = password
val actionResult: SignInResult = authClient.signIn(parameters)

if (actionResult is SignInResult.CodeRequired) {
    // Next step: submit code
} else if (actionResult is SignInError) {
    // Handle sign in errors
    when {
         actionResult.isUserNotFound() -> {
             // Handle "user not found" error
         }
         actionResult.isAuthNotSupported() -> {
             // Handle "authentication type not support" error
         }
         actionResult.isInvalidCredentials() -> {
             // Handle specific errors
         }
         else -> {
             // Handle other errors
         }
     }
}
  • SignInError указывает на результат неудачного действия, возвращенный signIn(parameters), поэтому результат действия не содержит ссылку на новое состояние.
  • Если actionResult is SignUpErrorпакет SDK для Android предоставляет служебные методы, чтобы вы могли проанализировать конкретные ошибки дальше:
    • Метод isUserNotFound() проверяет, входит ли пользователь с именем пользователя (адресом электронной почты), который не существует.
    • Метод isBrowserRequired() проверяет необходимость браузера (веб-резервного размещения) для завершения потока проверки подлинности. Этот сценарий происходит, если для завершения потока проверки подлинности недостаточно собственной проверки подлинности. Например, администратор настраивает электронную почту и пароль в качестве метода проверки подлинности, но приложение не может отправлять пароль в качестве типа проблемы или просто не поддерживает его. Выполните действия, описанные в разделе "Поддержка веб-резервного размещения" в приложении Android, чтобы обрабатывать сценарий, когда это происходит.
    • Метод isAuthNotSupported() проверяет, отправляет ли приложение тип вызова, который Microsoft Entra не поддерживает, это значение типа вызова, отличное от OOB и пароля. Дополнительные сведения о типах проблем.
    • При входе имени пользователя (электронной почты) и пароля метод isInvalidCredentials() проверяет, является ли сочетание имени пользователя и пароля неверным.

Обработка ошибок отправки кода

Для обработки ошибок в submitCode() методе используйте следующий фрагмент кода:

val submitCodeActionResult = nextState.submitCode(
    code = code
)
if (submitCodeActionResult is SignInResult.Complete) {
    // Sign in flow complete, handle success state.
} else if (submitCodeActionResult is SubmitCodeError && submitCodeActionResult.isInvalidCode()) {
    // Handle "invalid code" error
}
  • Ошибка SubmitCodeError указывает на результат неудачного действия, возвращенный submitCode() и поэтому результат действия не содержит ссылку на новое состояние.
  • Проверки isInvalidCode() конкретной ошибки. В этом случае для повторной обработки действия необходимо использовать предыдущую ссылку на состояние.

Чтобы получить новый секретный код электронной почты один раз, используйте следующий фрагмент кода:

val submitCodeActionResult = nextState.submitCode(
    code = code
)
if (submitCodeActionResult is SignInError && submitCodeActionResult.isInvalidCode) {
    // Inform the user that the submitted code was incorrect or invalid, then ask them to input a new email one-time passcode
    val newCode = retrieveNewCode()
    nextState.submitCode(
        code = newCode
    )
}

Вы выполнили все необходимые действия для успешного входа пользователя в приложение. Скомпилируйте и запустите приложение. Если все хорошо, вы должны иметь возможность предоставить сообщение электронной почты, получить код по электронной почте и использовать его для успешного входа пользователя.

Чтение утверждений маркера идентификатора

После получения маркера идентификатора приложение сможет получить утверждения, связанные с текущей учетной записью. Для этого используйте следующий фрагмент кода.

val preferredUsername = accountState.getClaims()?.get("preferred_username")
val city = accountState.getClaims()?.get("City")
val givenName = accountState.getClaims()?.get("given_name")
//custom attribute
val loyaltyNumber = accountState.getClaims()?.get("loyaltyNumber")

Ключ, используемый для доступа к значению утверждения, — это имя, указанное при добавлении атрибута пользователя в качестве утверждения токена.

Чтобы узнать, как добавить встроенные и настраиваемые атрибуты в качестве утверждений токена в статье "Добавление атрибутов пользователя" в статью о утверждениях токенов.

Выход пользователя

Чтобы выйти из него, необходимо удалить учетную запись, хранящуюся в кэше.

  1. Создайте пользовательский интерфейс, который включает в себя:

    • Кнопка выхода, которую пользователь выбирает для отправки запроса на выход.
  2. Чтобы выйти из пользователя, используйте следующий код:

    private fun performSignOut(accountState: AccountState) {
         CoroutineScope(Dispatchers.Main).launch {
             val accountResult = authClient.getCurrentAccount()
             if (accountResult is GetAccountResult.AccountFound) {
                 val signOutResult = accountResult.resultValue.signOut()
                 if (signOutResult is SignOutResult.Complete) {
                     // Show sign out successful UI
                 }
             }
         }
     }
    

Обработка ошибок выхода

Выход должен быть свободным от ошибок. Если возникают ошибки, проверьте результат ошибки с помощью следующего фрагмента кода:

val actionResult = accountResult.signOut()
if (actionResult is SignOutResult.Complete) {
    // Show sign out successful UI
} else {
    // Handle errors
}

Убедитесь, что вы включили инструкции импорта. Android Studio должна включать автоматические инструкции импорта.

Вы выполнили все необходимые действия, чтобы успешно выйти из приложения. Скомпилируйте и запустите приложение. Если все хорошо, вы сможете выбрать кнопку выхода, чтобы успешно выйти.

Настройка настраиваемого поставщика утверждений

Если вы хотите добавить утверждения из внешней системы в маркер, выданный приложению, используйте настраиваемый поставщик утверждений. Настраиваемый поставщик утверждений состоит из настраиваемого расширения проверки подлинности, вызывающего внешний REST API для получения утверждений из внешних систем.

Выполните действия, описанные в разделе "Настройка настраиваемого поставщика утверждений" для добавления утверждений из внешней системы в маркеры безопасности.