Повышение безопасности с помощью политик управления устройствами

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

Начиная с Android 2.2 (уровень API 8), платформа Android предлагает возможности управления устройствами на системном уровне через API-интерфейсы администрирования устройств.

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

Определите и объявите свою политику

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

Вы должны объявить выбранный набор политик, который будет применяться приложением, в файле res/xml/device_admin.xml . Манифест Android также должен ссылаться на объявленный набор политик.

Каждая объявленная политика соответствует некоторому количеству связанных методов политики устройств в DevicePolicyManager (два примера — определение минимальной длины пароля и минимального количества символов в верхнем регистре). Если приложение попытается вызвать методы, чья соответствующая политика не объявлена ​​в XML, это приведет к возникновению SecurityException во время выполнения. Другие разрешения, такие как force-lock , доступны, если приложение намерено управлять другими видами политики. Как вы увидите позже, в процессе активации администратора устройства список объявленных политик будет представлен пользователю на системном экране.

Следующий фрагмент объявляет политику ограничения паролей в res/xml/device_admin.xml :

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <limit-password />
    </uses-policies>
</device-admin>

XML-код декларации политики, указанный в манифесте Android:

<receiver android:name=".Policy$PolicyAdmin"
    android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data android:name="android.app.device_admin"
        android:resource="@xml/device_admin" />
    <intent-filter>
        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    </intent-filter>
</receiver>

Создайте приемник администрирования устройства

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

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

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

Котлин

class PolicyAdmin : DeviceAdminReceiver() {

    override fun onDisabled(context: Context, intent: Intent) {
        // Called when the app is about to be deactivated as a device administrator.
        // Deletes previously stored password policy.
        super.onDisabled(context, intent)
        context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE).edit().apply {
            clear()
            apply()
        }
    }
}

Ява

public static class PolicyAdmin extends DeviceAdminReceiver {

    @Override
    public void onDisabled(Context context, Intent intent) {
        // Called when the app is about to be deactivated as a device administrator.
        // Deletes previously stored password policy.
        super.onDisabled(context, intent);
        SharedPreferences prefs = context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE);
        prefs.edit().clear().commit();
    }
}

Активируйте администратора устройства

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

Рисунок 1. Экран активации пользователя, на котором вы можете предоставить описание политик вашего устройства.

Котлин

if (!policy.isAdminActive()) {

    val activateDeviceAdminIntent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)

    activateDeviceAdminIntent.putExtra(
            DevicePolicyManager.EXTRA_DEVICE_ADMIN,
            policy.getPolicyAdmin()
    )

    // It is good practice to include the optional explanation text to
    // explain to user why the application is requesting to be a device
    // administrator. The system will display this message on the activation
    // screen.
    activateDeviceAdminIntent.putExtra(
            DevicePolicyManager.EXTRA_ADD_EXPLANATION,
            resources.getString(R.string.device_admin_activation_message)
    )

    startActivityForResult(activateDeviceAdminIntent, REQ_ACTIVATE_DEVICE_ADMIN)
}

Ява

if (!policy.isAdminActive()) {

    Intent activateDeviceAdminIntent =
        new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);

    activateDeviceAdminIntent.putExtra(
        DevicePolicyManager.EXTRA_DEVICE_ADMIN,
        policy.getPolicyAdmin());

    // It is good practice to include the optional explanation text to
    // explain to user why the application is requesting to be a device
    // administrator. The system will display this message on the activation
    // screen.
    activateDeviceAdminIntent.putExtra(
        DevicePolicyManager.EXTRA_ADD_EXPLANATION,
        getResources().getString(R.string.device_admin_activation_message));

    startActivityForResult(activateDeviceAdminIntent,
        REQ_ACTIVATE_DEVICE_ADMIN);
}

Если пользователь выбирает «Активировать», приложение становится администратором устройства и может начать настройку и применение политики.

Приложение также должно быть подготовлено к обработке ситуаций возврата, когда пользователь отказывается от процесса активации, нажимая кнопку «Отмена», клавишу «Назад» или клавишу «Домой». Таким образом, onResume() в действии по настройке политики должен иметь логику для повторной оценки состояния и предоставления пользователю возможности активации администратора устройства, если это необходимо.

Реализация контроллера политики устройства

После успешной активации администратора устройства приложение настраивает диспетчер политики устройств с использованием запрошенной политики. Имейте в виду, что новые политики добавляются в Android с каждым выпуском. Целесообразно выполнять проверку версий в вашем приложении, если вы используете новые политики и поддерживаете старые версии платформы. Например, политика «Минимум верхнего регистра пароля» доступна только для уровня API 11 (Honeycomb) и выше. Следующий код демонстрирует, как можно проверить версию во время выполнения.

Котлин

private lateinit var dpm: DevicePolicyManager
private lateinit var policyAdmin: ComponentName

dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
policyAdmin = ComponentName(context, PolicyAdmin::class.java)

dpm.apply {
    setPasswordQuality(policyAdmin, PASSWORD_QUALITY_VALUES[passwordQuality])
    setPasswordMinimumLength(policyAdmin, passwordLength)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        setPasswordMinimumUpperCase(policyAdmin, passwordMinUpperCase)
    }
}

Ява

DevicePolicyManager dpm = (DevicePolicyManager)
        context.getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName policyAdmin = new ComponentName(context, PolicyAdmin.class);

dpm.setPasswordQuality(policyAdmin, PASSWORD_QUALITY_VALUES[passwordQuality]);
dpm.setPasswordMinimumLength(policyAdmin, passwordLength);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    dpm.setPasswordMinimumUpperCase(policyAdmin, passwordMinUpperCase);
}

На этом этапе приложение может применить политику. Хотя приложение не имеет доступа к фактическому используемому паролю блокировки экрана, через API диспетчера политик устройств оно может определить, соответствует ли существующий пароль требуемой политике. Если окажется, что существующего пароля блокировки экрана недостаточно, API администрирования устройства не предпримет автоматически корректирующих действий. Приложение несет ответственность за явный запуск экрана смены системного пароля в приложении «Настройки». Например:

Котлин

if (!dpm.isActivePasswordSufficient) {
    // Triggers password change screen in Settings.
    Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD).also { intent ->
        startActivity(intent)
    }
}

Ява

if (!dpm.isActivePasswordSufficient()) {
    ...
    // Triggers password change screen in Settings.
    Intent intent =
        new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
    startActivity(intent);
}

Обычно пользователь может выбрать один из доступных механизмов блокировки, например «Нет», «Шаблон», «ПИН-код» (цифровой) или «Пароль» (буквенно-цифровой). Когда настроена политика паролей, те типы паролей, которые более слабы, чем те, которые определены в политике, отключаются. Например, если настроено качество пароля «Числовой», пользователь может выбрать только ПИН-код (цифровой) или Пароль (буквенно-цифровой).

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

Котлин

when {
    !dpm.isAdminActive(policyAdmin) -> {
        // Activates device administrator.
        ...
    }
    !dpm.isActivePasswordSufficient -> {
        // Launches password set-up screen in Settings.
        ...
    }
    else -> {
        // Grants access to secure content.
        ...
        startActivity(Intent(context, SecureActivity::class.java))
    }
}

Ява

if (!dpm.isAdminActive(..)) {
    // Activates device administrator.
    ...
} else if (!dpm.isActivePasswordSufficient()) {
    // Launches password set-up screen in Settings.
    ...
} else {
    // Grants access to secure content.
    ...
    startActivity(new Intent(context, SecureActivity.class));
}