Подходы для создания системы управления доступом устройства на ОС Android. Что изменилось в 2023 году?

от автора

Максим Денисов, разработчик в Лиге Цифровой Экономики, поделился опытом создания системы управления доступом на Android и рассказал, как менялся подход к контролю доступа.

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

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

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

Разработка началась в 2015 году, когда 5-я версия Android была последней.

1.           Подход на основе блокирующей view

1.1.  Блокировка

Суть подхода — работа блокирующего окна, которое отображается поверх всех остальных. После авторизации оно закрывается.

В манифесте приложения нужно добавить следующее разрешение:

<uses-permission android:name=»android.permission.SYSTEM_ALERT_WINDOW» />

С API 23 необходимо явно его указывать. Поэтому при настройке приложения администратор должен выбрать «Разрешать всегда».

У блокирующего экрана добавить свойства:

WindowManager.LayoutParams.TYPE_SYSTEM_ALERT

WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN

Кроме того, следует создать сервис, в котором ресивер отлавливает выключение экрана и вызывает блокирующую view.

private BroadcastReceiver screenStatusReceiver = new BroadcastReceiver() {    @Override    public void onReceive(Context context, Intent intent) {        if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {            startLockScreenActivity(context);        }    }   public static void startLockScreenActivity(Context context) {    Intent activityIntent = new Intent(context, LockActivity.class);    activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);      activityIntent.addFlags(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);    context.startActivity(activityIntent); }

Чтобы пользователь не мог удалить приложение, последнему выдаются права администратора.

Intent activateDeviceAdmin = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);

activateDeviceAdmin.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, policyManager.getAdminComponent());

activateDeviceAdmin.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, «After activating admin, you will be able to block application uninstallation.»);

startActivityForResult(activateDeviceAdmin, PolicyManager.DPM_ACTIVATION_REQUEST_CODE);

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

devicePolicyManager.wipeData(0);

1.2.  События безопасности

Для хранения событий пользователя применялась локальная база данных.

@Entity(tableName = «events»)

data class Event(

       @PrimaryKey(autoGenerate = true)

       @ColumnInfo(name = «id»)

       val id: Int,

       @ColumnInfo(name = «login»)

       val login: String? = null,

……

 Синхронизация происходила по таймеру.

internal inner class SyncEventTimer : TimerTask() {    override fun run() {        Timber.tag(TAG).d("SyncEventTimer")        GlobalScope.launch(Dispatchers.IO) {            try {                sendFromLocal()            } catch (e: Exception) {                Timber.tag(TAG).e(e)            }        }    } }

1.3        Обновление

Обновление происходит через загрузку apk на устройство и вызов следующего интента:

          Intent intent = new Intent( Intent.ACTION_INSTALL_PACKAGE

intent.setData( apkUri );

           intent.setFlags( Intent.FLAG_GRANT_READ_URI_PERMISSION );

           context.startActivity( intent );

Со временем появились серьезные ограничения. В 9-й и 10-й версиях Android появилась возможность убрать блокирующую view, а также не удается блокировать запуск других приложений. Когда происходило обновление, у пользователя появлялась возможность закрыть блокировщик — он «снимался» в момент обновления.

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

Поэтому для новых версий Android такой подход, к сожалению, не применим.

2.               Подход на основе библиотеки knox от Samsung

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

Для ее работы в манифесте добавляются разрешения:

<uses-permission android:name="com.samsung.android.knox.permission.KNOX_KIOSK_MODE" /> <uses-permission android:name="com.samsung.android.knox.permission.KNOX_CUSTOM_SYSTEM " /> <uses-permission android:name="com.samsung.android.knox.permission.KNOX_APP_MGMT" /> <uses-permission android:name="com.samsung.android.knox.permission.KNOX_ADVANCED_SECURITY" /> Для работы библиотеки необходимо ввести ключ лицензии. val mSKL = KnoxEnterpriseLicenseManager.getInstance(context) mSKL.activateLicense(“key”, context.packageName) 

Выдача разрешений без запроса пользователю делалась так:

runtimePermissions.add(«android.permission.WRITE_EXTERNAL_STORAGE»);

Установка блокирующего приложения — следующим образом:

mKioskMode?.enableKioskMode(pkgName)

Отключение приложений на устройстве:

 EnterpriseDeviceManager edm = EnterpriseDeviceManager.getInstance(context);

 ApplicationPolicy appPolicy = edm.getApplicationPolicy();

appPolicy.setDisableApplication(“com.test.app”)

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

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

3. Подход на основе владельца устройства

3.1.  Установка режима device-owner

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

adb shell dpm set-device-owner ru.company.screenlocker/.AdminReceiver

3.2.  Выдача разрешений

В этом режиме приложению можно выдать любые необходимые разрешения:

val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager val cn = ComponentName(context, AdminReceiver::class.java)  dpm.setPermissionGrantState(    cn, context.packageName,    Manifest.permission.REQUEST_INSTALL_PACKAGES,    DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED )

3.3.  Запрет на изменение приложения

Запретить пользователю менять приложение можно следующей командой:

val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager

val cn = ComponentName(context, AdminReceiver::class.java)

dpm.addUserRestriction(cn, UserManager.DISALLOW_APPS_CONTROL)

3.4.  Включить режим блокировки задач

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

activity.startLockTask()

3.5.  Установить свой рабочий стол

Получить список всех приложений с иконками:

val allApps = packageManager.queryIntentActivities(i, 0)    for (ri in allApps) {        val app = DesktopAppInfo()        app.label = ri.loadLabel(packageManager)        app.packageName = ri.activityInfo.packageName        app.icon = ri.activityInfo.loadIcon(packageManager)        loadList.add(app)    }

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

На мой взгляд, это самый актуальный на сегодняшний день формат — работает на всех устройствах Android и на новых версиях ОС. Однако для установки приложения администратора необходимо форматировать устройство.

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

____________________________________________

В этом материале я описал изменение подхода к контролю корпоративной техники — от устаревшего к актуальному и на сегодняшний день. Имели ли вы дело с каким-либо их них?


ссылка на оригинал статьи https://habr.com/ru/company/digitalleague/blog/722232/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *