Реализовать учетные записи пользователей

Для регистрации в корпоративной сети Android существует два основных типа учетных записей пользователей: управляемые учетные записи Google Play и управляемые учетные записи Google. Управляемые учетные записи Google Play ориентированы на устройство, то есть они не привязаны к конкретной учетной записи Google пользователя. В отличие от них, управляемые учетные записи Google связаны с корпоративной учетной записью Google пользователя, что улучшает пользовательский опыт, обеспечивая постоянный вход в систему на устройстве.

Раньше стандартом были управляемые учетные записи Google Play. Однако теперь Google рекомендует всем новым разработчикам использовать улучшенный процесс регистрации, который по умолчанию предусматривает создание управляемых учетных записей Google.

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

Обзор

Усовершенствованный процесс регистрации устройств упрощает их настройку за счет использования нескольких новых компонентов и изменения способа реализации пользовательских контроллеров политик устройств (DPC). Этот новый подход требует интеграции пользовательских решений DPC с SDK Android Management API (AMAPI) и Android Device Policy для выполнения функций подготовки устройств и регистрации пользователей.

AMAPI SDK предоставляет необходимые API для взаимодействия с политикой Android-устройств на самом устройстве. На стороне сервера решения Enterprise Mobility Management (EMM) будут использовать API Play EMM для генерации токенов регистрации, необходимых для запуска процесса регистрации устройства.

Приложение Android Device Policy теперь играет центральную роль в обработке операций на стороне устройства. Для управления его установкой и необходимыми обновлениями на устройстве используется SDK AMAPI . Android Device Policy также берет на себя процесс аутентификации пользователя, обрабатывая аутентификацию напрямую и предоставляя идентификатор пользователя системе EMM. Если Google по какой-либо причине не может аутентифицировать пользователя, создается и добавляется на устройство новая управляемая учетная запись Google Play в качестве резервной.

Ключевой частью нового процесса регистрации является управление доступом устройства к сервисам Google. По умолчанию устройства запускаются в ограниченном состоянии, и EMM играет решающую роль в предоставлении доступа после того, как устройство будет соответствовать требованиям.

Интеграция API

Прежде чем начать, убедитесь, что вы используете последнюю версию клиента Play EMM API и AMAPI SDK.

Руководство по внедрению системы регистрации

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

Подготовьте окружающую среду

Перед началом настройки учетной записи необходимо подготовить среду устройства. Эта подготовка включает в себя обновление Play Store до последней версии и автоматическую установку политики Android Device Policy ( com.google.android.apps.work.clouddpc ) на устройство. Установка политики Android Device Policy необходима, поскольку она содержит критически важные компоненты процесса настройки учетной записи. EMM-менеджерам не нужно выполнять ручную подготовку среды. Вместо этого им следует использовать EnvironmentClient , как описано в документации, и следовать предоставленным примерам кода.

Пример кода

Прежде чем использовать API AccountSetup для добавления рабочей учетной записи на устройство, DPC должен сначала убедиться, что среда устройства готова.

  • Используйте EnvironmentClientFactory для создания экземпляра EnvironmentClient и вызовите prepareEnvironment или prepareEnvironmentAsync

    val notificationReceiverServiceName = ComponentName(context,
    NotificationReceiver::class.java)
    
    // An EMM should implement android.app.admin.DeviceAdminReceiver and use that
    // class to instantiate a ComponentName
    
    val admin = ComponentName(this, com.example.dpc.DeviceAdminReceiver::class.java)
    
    EnvironmentClientFactory.create(context)
        .prepareEnvironment(
            PrepareEnvironmentRequest.builder()
                .setRoles(
                    listOf(
                        Role.builder().setRoleType(
                            Role.RoleType.DEVICE_POLICY_CONTROLLER
                        ).build()
                    )
                )
        .setAdmin(admin)
                .build(),
              notificationReceiverServiceName,
            )
    
    [Proceed with AccountSetup]
    
    

Эта операция может занять несколько секунд или минут, поскольку могут устанавливаться или обновляться приложения для проверки корректной работы системы. Google рекомендует запускать этот процесс как можно раньше в фоновом режиме и отображать соответствующий пользовательский интерфейс, пока пользователь ожидает. После завершения операции устройство будет готово к использованию API AccountSetup системой DPC.

Процесс зачисления

EMM-системы должны отказаться от использования users.generateAuthenticationToken() и users.insert() для всех устройств. Вместо этого EMM-системы должны вызывать API на устройстве для аутентификации конечного пользователя. Новый API будет возвращать идентификатор userId и email в DPC. Если Google не сможет аутентифицировать пользователя, будет создана и добавлена ​​к устройству управляемая учетная запись Google Play. В этом случае Google вернет userId этой учетной записи.

Google теперь использует токены регистрации, которые необходимо передавать в API аутентификации. EMM определяют, когда и как создавать токен, и он может быть частью существующей полезной нагрузки регистрации (например, QR-кода или конфигурации Zero-touch).

Однако Google рекомендует создавать токен по запросу и заменять существующий API для управляемых учетных записей Google Play новым API, чтобы свести изменения к минимуму.

Типичная интеграция DPC с предыдущими API.
Figure 1. Typical DPC integration with previous APIs
Пример интеграции DPC с новыми API для устройств без пользовательского интерфейса.
Рисунок 2. Пример интеграции DPC с новыми API для устройств без пользовательского интерфейса.
Пример интеграции DPC с новыми API для пользовательских устройств.
Рисунок 3. Пример интеграции DPC с новыми API для пользовательских устройств.

Усовершенствованный процесс регистрации в системе DPC включает следующие шаги:

Важно: при регистрации устройства с пользовательским DPC учетная запись Google, добавленная к устройству, изначально находится в отключенном состоянии. Это означает, что доступ к сервисам Google, включая Google Play, изначально ограничен.

Этот статус по умолчанию «отключено» и последующее требование к EMM пометить устройство как соответствующее требованиям (например, путем вызова Devices.SetState) применяются исключительно при следующих условиях:

  1. The organization has verified ownership of their domain with Google.
  2. ИТ-администратор явно включил управление сторонними мобильными устройствами Android для конкретного организационного подразделения (OU) пользователя в консоли администратора Google.
  1. Create Enrollment Token: The EMM creates an enrollment token using the Play EMM API.
  2. Подготовка среды: Пользовательский DPC использует процесс подготовки среды для проверки готовности устройства к регистрации.
  3. Инициирование регистрации: Пользовательский DPC вызывает API startAccountSetup из AMAPI SDK, передавая токен регистрации. Примечание: Перед вызовом этого API DPC должен быть либо владельцем устройства, либо владельцем профиля.
  4. Запуск процесса аутентификации Google: При необходимости пользовательский DPC вызывает API launchAuthenticationActivity из AMAPI SDK, передавая AccountSetupAttempt . Это запускает процесс аутентификации Google, возвращая пользователя в пользовательский DPC после успешной аутентификации. Пользователь также может пропустить этот процесс. В этом случае на устройство будет добавлена ​​управляемая учетная запись Google Play. Этот параметр можно настроить с помощью googleAuthenticationOptions .
  5. Завершение регистрации: AMAPI SDK уведомляет пользовательский DPC о результате регистрации.
  6. Включение сервисов Google: После того, как пользовательский DPC полностью настроит устройство и подтвердит его соответствие всем корпоративным политикам, сервер EMM должен вызвать метод Devices.setState() с параметром accountState , установленным в значение "enabled" .

    • Почему это важно: Этот вызов API подтверждает соответствие устройства требованиям.
    • Последствия отсутствия вызова Devices.setState(setStateRequest) учетная запись останется в состоянии «отключено». Пользователь не сможет получить доступ к Google Play (для установки или обновления приложений) и другим сервисам Google, требующим аутентификации учетной записи.

Управление состоянием устройства и доступом к службам.

После первоначальной регистрации EMM отвечает за поддержание доступа устройства к сервисам Google в соответствии с его статусом соответствия требованиям.

Handling Service Disruptions: BAD_DEVICE_MANAGEMENT

Если доступ устройства к сервисам Google заблокирован, сервисы Google Play (GMSCore) отправят Intent с действием: com.google.android.gms.auth.BAD_DEVICE_MANAGEMENT . Это может произойти по нескольким причинам:

  • The EMM never called Devices.setState("enabled") after the initial device enrollment.
  • Устройство больше не соответствует политикам EMM, и EMM еще не активировал его повторно.
  • EMM явно устанавливает состояние устройства в "отключено", вызывая метод Devices.setState() с параметром accountState, установленным в "отключено". Это может быть связано с соображениями безопасности, административными действиями или другими причинами.

Данный Intent содержит код состояния, например, "ThirdPartyDeviceManagementRequired" .

Пользовательские DPC-приложения ОБЯЗАТЕЛЬНО должны реализовывать интерфейс BroadcastReceiver для прослушивания этого намерения BAD_DEVICE_MANAGEMENT .

Получив это сообщение, DPC должен:

  1. Повторная оценка соответствия: проверьте, соответствует ли устройство в настоящее время всем правилам, установленным EMM.
  2. Примите меры:
    • Если соответствует требованиям: DPC должен уведомить сервер EMM. Затем сервер EMM должен вызвать Devices.setState() с accountState , установленным в значение "enabled" для конкретного идентификатора пользователя и идентификатора устройства, чтобы попытаться восстановить доступ к сервису.
    • Если устройство не соответствует требованиям: После устранения проблем и обеспечения соответствия устройству требованиям, EMM должен вызвать Devices.setState() .

Этот механизм гарантирует возможность обнаружения и восстановления после ситуаций, когда устройство теряет доступ к сервисам Google.

Вопросы поглощения предприятий

Могут происходить изменения типа учетной записи организации (например, с ManagedGoogleDomainType.TYPE_TEAM на ManagedGoogleDomainType.TYPE_DOMAIN ). Хотя этот процесс обычно не нарушает привязку EMM, иногда он может нарушить доступ к сервисам Google на устройствах.

EMM-системам следует учитывать, что если пользователи сообщают о проблемах с доступом к сервису после известного события захвата сети, даже если устройство, по-видимому, соответствует политикам EMM, может потребоваться вызов Devices.setState() для повторной синхронизации состояния устройства с бэкэндами Google в рамках новой клиентской структуры. Проактивные вызовы для всех устройств после захвата сети, как правило, не требуются, но это ключевой инструмент для решения проблем с доступом.

Настройка учетной записи - пример кода

  1. Для инициирования попытки настройки учетной записи вызывающее приложение может использовать AccountSetupClient и вызвать либо метод startAccountSetup() , либо метод startAccountSetupFuture() . Пример реализации см. в следующем фрагменте кода:

    // Create AccountSetupClient
    val client = AccountSetupClientFactory.create(
        this,
        activityResultRegistry
    )
    lifecycle.addObserver(client.lifecycleObserver)
    
    // Create adminComponent
    val notificationReceiver = ComponentName(this, AccountSetupNotificationReceiver::class.java)
    // Helper method to get enrollment token created with Play EMM API
    val enrollmentToken = getEnrollmentToken()
    val request =
        StartAccountSetupRequest.builder()
            .setEnrollmentToken(enteredText)
            .setNotificationReceiverServiceComponentName(notificationReceiver)
            .setAdminComponentName(
                ComponentName(this, com.example.dpc.DeviceAdminReceiver::class.java))
            .build()
    try {
        val accountSetupAttempt = client.startAccountSetup(request)
        // handle attempt
    } catch (e: Exception) {
        // handle exception
    }
    
  2. Implement AccountSetupListener interface and provide an implementation for how to handle the received status updates.

  3. Расширьте NotificationReceiverService и предоставьте экземпляр AccountSetupListener , созданный на шаге 2, переопределив getAccountSetupListener() .

    // Handles account setup changes
    class AccountSetupNotificationReceiver :
          NotificationReceiverService(),
          AccountSetupListener {
    
        override fun getAccountSetupListener(): AccountSetupListener = this
    
        override fun onAccountSetupChanged(accountSetupAttempt:
      AccountSetupAttempt) {
    
            when (accountSetupAttempt.state.kind) {
                StateCase.ADDED_ACCOUNT -> {
                    val enterpriseAccount = state.addedAccount()
                    val userId = enterpriseAccount.userId
                    val deviceId = enterpriseAccount.deviceId
                    // Handle account added state.
    
                    // IMPORTANT: The device/account is now added but *DISABLED*
                    // for Google services. Your EMM backend MUST be notified to
                    // perform policy compliance checks and then call Devices.setState()
                    // to activate Google Play and other services.
    
                }
                StateCase.AUTHENTICATION_ACTIVITY_LAUNCH_REQUIRED -> {
                    val request = LaunchAuthenticationActivityRequest.builder()
                .setAccountSetupAttempt(accountSetupAttempt)
                .build();
                    // Send the attempt to the foreground activity to call:
                    accountSetupClient.launchAuthenticationActivity(request)
                }
                StateCase.ACCOUNT_SETUP_ERROR -> {
                    // Handle error state.
                    val failureReason = state.accountSetupError().failureReason
                }
                else -> {
                    // Handle unknown account setup attempt state.
                }
            }
        }
    }
    
    
  4. Add the extended NotificationReceiverService class to your AndroidManifest.xml and verify it is exported.

      <application>
        <service
            android:name = ".accountsetup.AccountSetupNotificationReceiver"
            android:exported = "true" />
      </application>
    

    Если ваше приложение ориентировано на SDK 30 или более позднюю версию, то в файле AndroidManifest.xml необходимо добавить элемент queries, чтобы указать, что оно будет взаимодействовать с ADP.

      <queries>
        <package android:name="com.google.android.apps.work.clouddpc" />
      </queries>
    

Руководство по тестированию

В этом разделе представлен набор рекомендаций и лучших практик для тестирования вашей реализации.

PrepareEnvironment тестирования

  1. Получение текущего состояния устройства: EMM запущен.

    adb shell dumpsys package com.google.android.apps.work.clouddpc | grep versionName
    

    to get the version of the Android Device Policy present on the device. If the Android Device Policy is not installed, an empty output is expected.

  2. Integrate PrepareEnvironment: The custom DPC invokes prepareEnvironment API in the AMAPI SDK, passing the correct request.

  3. Ожидание результата PrepareEnvironment: Пользовательский DPC ожидает завершения процесса prepareEnvironment .

  4. Confirm PrepareEnvironment success: On completion, EMM runs again

    adb shell dumpsys package com.google.android.apps.work.clouddpc | grep versionName
    

    This time the Android Device Policy version should be higher than in step 1.

Проверка аутентификации учетной записи Google.

  1. Create test enterprise: The EMM creates a test domain Google enterprise linked to a test EMM, with enterprises.generateSignupUrl .
  2. Enable Google authentication: The EMM enables Google authentication for the test enterprise following these instructions in the Google Admin console.
  3. Create Enrollment Token: The EMM creates an enrollment token using the Play EMM API with type userDevice .
  4. Initiate Enrollment: The custom DPC invokes the startAccountSetup API in the AMAPI SDK, passing the enrollment token.
  5. Launch activity required: The AMAPI SDK notifies the custom DPC that an activity must be launched to authenticate the user.
  6. Аутентификация пользователя: Пользовательский DPC вызывает launchAuthenticationActivity для запуска активности. Пользователь проходит аутентификацию с помощью управляемой учетной записи Google (часть предприятия, созданного на шаге 1).
  7. Завершение регистрации: AMAPI SDK уведомляет пользовательский DPC о результате регистрации.

Тест пропускает аутентификацию Google.

Мы будем использовать описанную ранее конфигурацию.

На этот раз, на шаге 7, пользователь нажимает «Пропустить» вместо аутентификации с помощью своей учетной записи Google. Регистрация завершается успешно, и на устройстве создается служебная учетная запись (т.е. AuthenticationType — анонимный).

Тестирование беспилотных устройств

The improved custom DPC enrollment flow utilizes the followeing steps, when Google authentication is disabled:

  1. Create a test enterprise: This can be the same enterprise as created previously.
  2. Create Enrollment Token: The EMM creates an enrollmenttoken using the Play EMM API with type userlessDevice .
  3. Инициирование регистрации: Пользовательский DPC вызывает API startAccountSetup из AMAPI SDK, передавая токен регистрации.
  4. Завершение регистрации: AMAPI SDK уведомляет пользовательский DPC о результате регистрации.