Аутентификация на носимых устройствах: Credential Manager

Приложения Wear OS могут работать автономно, без сопутствующего приложения. Это означает, что приложению Wear OS необходимо самостоятельно управлять аутентификацией при доступе к данным из Интернета. Но небольшой размер экрана часов и ограниченные возможности ввода ограничивают возможности аутентификации, которые может использовать приложение Wear OS.

В этом руководстве приведены инструкции по рекомендуемому методу аутентификации для приложений Wear OS — Credential Manager.

Чтобы узнать больше о том, как разработать удобный процесс входа в систему, ознакомьтесь с руководством по пользовательскому опыту входа в систему .

Предварительные соображения

Прежде чем приступить к реализации, примите во внимание следующие моменты.

Гостевой режим

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

Пользователи могут обнаружить и установить ваше приложение Wear, не используя мобильное приложение, поэтому у них может не быть учетной записи, и они могут не знать, какие функции оно предлагает. Убедитесь, что функциональность гостевого режима точно демонстрирует функции вашего приложения.

Некоторые устройства могут оставаться разблокированными дольше

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

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

val wristDetectionEnabled =
        isWristDetectionAutoLockingEnabled(applicationContext)

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

Менеджер по учетным данным

Credential Manager — рекомендуемый API для аутентификации на Wear OS. Он обеспечивает более безопасную среду для пользователей, чтобы они могли входить в приложения Wear OS в автономном режиме, без необходимости подключать сопряженный телефон и запоминать пароль.

В этом документе изложена информация, необходимая разработчикам для внедрения решения Credential Manager со стандартными механизмами аутентификации, которые оно размещает, а именно:

  • Пароли
  • Пароли
  • Федеративные удостоверения (например, вход через Google)

В этом руководстве также приводятся инструкции по переносу других приемлемых методов аутентификации Wear OS ( Data Layer Token Sharing и OAuth ) в качестве резервных копий для Credential Manager, а также специальные инструкции по выполнению перехода с устаревшей автономной кнопки входа Google на встроенную версию Credential Manager.

Пароли на Wear OS

Разработчикам настоятельно рекомендуется внедрять пароли в свои реализации Wear OS Credential Manager. Пароли — это новый отраслевой стандарт для аутентификации конечных пользователей, и они несут несколько существенных преимуществ для пользователей.

Пароли проще

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

Пароли безопаснее

  • Разработчики сохраняют на сервере только открытый ключ, а не пароль, а это значит, что злоумышленникам гораздо сложнее взломать серверы и гораздо сложнее устранить неполадки в случае взлома.
  • Пароли обеспечивают защиту от фишинга. Пароли работают только на зарегистрированных веб-сайтах и ​​в приложениях; пользователя невозможно обмануть и заставить пройти аутентификацию на мошенническом сайте, поскольку браузер или ОС выполняют проверку.
  • Пароли устраняют необходимость отправки SMS-сообщений, делая аутентификацию более экономичной.

Внедрить пароли

Включает настройку и руководство для всех типов внедрения.

Настраивать

  1. Установите целевой уровень API на 35 в файле build.gradle вашего модуля приложения:

    android {
        defaultConfig {
            targetSdkVersion(35)
        }
    }
    
  2. Добавьте следующие строки в файл build.gradle для вашего приложения или модуля, используя последнюю стабильную версию из справочника релизов androidx.credentials .

    androidx.credentials:credentials:1.5.0
    androidx.credentials:credentials-play-services-auth:1.5.0
    

Встроенные методы аутентификации

Поскольку Credential Manager представляет собой унифицированный API, этапы внедрения для Wear OS такие же, как и для любого другого типа устройства.

Используйте мобильные инструкции для начала работы и реализации поддержки ключей доступа и паролей.

Шаги по добавлению поддержки Sign in With Google в Credential Manager ориентированы на мобильную разработку, но шаги те же самые на Wear OS. См. раздел Переход от Legacy Sign in With Google для особых соображений в этом случае.

Обратите внимание: поскольку учетные данные невозможно создать в Wear OS, вам не нужно реализовывать методы создания учетных данных, упомянутые в мобильных инструкциях.

Резервные методы аутентификации

Есть еще два приемлемых метода аутентификации для приложений Wear OS: OAuth 2.0 (любой вариант) и Mobile Auth Token Data Layer Sharing. Хотя эти методы не имеют точек интеграции в API Credential Manager, их можно включить в ваш UX-поток Credential Manager в качестве резервных вариантов на случай, если пользователи закроют экран Credential Manager.

Чтобы обработать действие пользователя по закрытию экрана Credential Manager, перехватите исключение NoCredentialException как часть логики GetCredential и перейдите к собственному пользовательскому интерфейсу аутентификации.

yourCoroutineScope.launch {
    try {
      val response = credentialManager.getCredential(activity, request)
      signInWithCredential(response.credential)
    } catch (e: GetCredentialCancellationException) {
      navigateToFallbackAuthMethods()
    }
}

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

Совместное использование токенов уровня данных

Приложение-компаньон для телефона может безопасно передавать данные аутентификации в приложение Wear OS с помощью API Wearable Data Layer. Передавайте учетные данные как сообщения или как элементы данных.

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

Важно: Ваше приложение Wear OS должно предлагать по крайней мере один другой метод аутентификации, поскольку эта опция работает только на сопряженных с Android часах, когда установлено соответствующее мобильное приложение. Предоставьте альтернативный метод аутентификации для пользователей, у которых нет соответствующего мобильного приложения или чье устройство Wear OS сопряжено с устройством iOS.

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

val token = "..." // Auth token to transmit to the Wear OS device.
val dataClient: DataClient = Wearable.getDataClient(context)
val putDataReq: PutDataRequest = PutDataMapRequest.create("/auth").run {
    dataMap.putString("token", token)
    asPutDataRequest()
}
val putDataTask: Task<DataItem> = dataClient.putDataItem(putDataReq)

Прослушивайте события изменения данных в приложении Wear OS, как показано в следующем примере:

val dataClient: DataClient = Wearable.getDataClient(context)
dataClient.addListener{ dataEvents ->
    dataEvents.forEach { event ->
        if (event.type == DataEvent.TYPE_CHANGED) {
            val dataItemPath = event.dataItem.uri.path ?: ""
            if (dataItemPath.startsWith("/auth")) {
                val token = DataMapItem.fromDataItem(event.dataItem).dataMap.getString("token")
                // Display an interstitial screen to notify the user that
                // they're being signed in.
                // Then, store the token and use it in network requests.
            }
        }
    }
}

Дополнительную информацию об использовании Wearable Data Layer см. в разделе Отправка и синхронизация данных на Wear OS .

Использовать OAuth 2.0

Wear OS поддерживает два потока на основе OAuth 2.0, которые описаны в следующих разделах:

  • Предоставление кода авторизации с ключом подтверждения для обмена кодами (PKCE), как определено в RFC 7636
  • Разрешение на авторизацию устройства (DAG), как определено в RFC 8628
Ключ подтверждения для обмена кодами (PKCE)

Для эффективного использования PKCE используйте RemoteAuthClient . Затем, чтобы выполнить запрос аутентификации из вашего приложения Wear OS к поставщику OAuth, создайте объект OAuthRequest . Этот объект состоит из URL-адреса вашей конечной точки OAuth для получения токена и объекта CodeChallenge .

Следующий код показывает пример создания запроса аутентификации:

val request = OAuthRequest.Builder(this.applicationContext)
    .setAuthProviderUrl(Uri.parse("https://...."))
    .setClientId(clientId)
    .setCodeChallenge(codeChallenge)
    .build()

После создания запроса на аутентификацию отправьте его в сопутствующее приложение с помощью метода sendAuthorizationRequest() :

val client = RemoteAuthClient.create(this)
client.sendAuthorizationRequest(request,
    { command -> command?.run() },
    object : RemoteAuthClient.Callback() {
        override fun onAuthorizationResponse(
            request: OAuthRequest,
            response: OAuthResponse
        ) {
            // Extract the token from the response, store it, and use it in
            // network requests.
        }

        override fun onAuthorizationError(errorCode: Int) {
            // Handle any errors.
        }
    }
)

Этот запрос инициирует вызов сопутствующего приложения, которое затем представляет пользовательский интерфейс авторизации в веб-браузере на мобильном телефоне пользователя. Поставщик OAuth 2.0 аутентифицирует пользователя и получает его согласие на запрошенные разрешения. Ответ отправляется на автоматически сгенерированный URL-адрес перенаправления.

После успешной или неудачной авторизации сервер OAuth 2.0 перенаправляет на URL, указанный в запросе. Если пользователь одобряет запрос на доступ, то ответ содержит код авторизации. Если пользователь не одобряет запрос, то ответ содержит сообщение об ошибке.

Ответ имеет форму строки запроса и выглядит как один из следующих примеров:

  https://wear.googleapis.com/3p_auth/com.your.package.name?code=xyz
  https://wear.googleapis-cn.com/3p_auth/com.your.package.name?code=xyz

Это загружает страницу, которая направляет пользователя в сопутствующее приложение. Сопутствующее приложение проверяет URL ответа и передает ответ в ваше приложение Wear OS. с помощью API onAuthorizationResponse .

Затем приложение для часов может обменять код авторизации на токен доступа.

Разрешение на использование устройства

При использовании Device Authorization Grant пользователь открывает URI проверки на другом устройстве. Затем сервер авторизации просит его одобрить или отклонить запрос.

Чтобы упростить этот процесс, используйте RemoteActivityHelper для открытия веб-страницы на сопряженном мобильном устройстве пользователя, как показано в следующем примере:

// Request access from the authorization server and receive Device Authorization
// Response.
val verificationUri = "..." // Extracted from the Device Authorization Response.
RemoteActivityHelper.startRemoteActivity(
    this,
    Intent(Intent.ACTION_VIEW)
        .addCategory(Intent.CATEGORY_BROWSABLE)
        .setData(Uri.parse(verificationUri)),
    null
)
// Poll the authorization server to find out if the user completed the user
// authorization step on their mobile device.

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

Переход от устаревшего входа в систему с помощью Google

Credential Manager имеет специальную точку интеграции для кнопки Sign in With Google. Раньше эту кнопку можно было добавить в любом месте UX аутентификации приложения, но с ее включением в Credential Manager старая опция теперь устарела.

// Define a basic SDK check.
fun isCredentialManagerAvailable(): Boolean {
 return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM
}

// Elsewhere in the code, use it to selectively disable the legacy option.
Button(
  onClick = {
    if (isCredentialManagerAvailable()) {
      Log.w(TAG, "Devices on API level 35 or higher should use
                  Credential Manager for Sign in with Google")
    } else {
      navigateToSignInWithGoogle()
    }},
  enabled = !isCredentialManagerAvailable(),
  label = { Text(text = stringResource(R.string.sign_in_with_google)) },
  secondaryLabel = { Text(text = "Disabled on API level 35+")
  }
)