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


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

применяется к: белый круг с серым символом X. арендаторы рабочей силы зеленый круг с символом белой галочки. внешние клиенты (подробнее)

В этом руководстве показано, как выполнить вход и выход пользователя, используя однократный код доступа через электронную почту или имя пользователя и пароль, в мобильном приложении 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, что указывает на то, что SDK ожидает, что приложение отправит одноразовый код доступа, отправленный на адрес электронной почты пользователя.
    • Объект 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 для получения утверждений из внешних систем.

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