Определите пользовательское разрешение приложения

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

Фон

Android — это операционная система с разделением привилегий, в которой каждое приложение запускается с отдельным системным идентификатором (идентификатором пользователя Linux и идентификатором группы). Части системы также разделены на отдельные идентификаторы. Таким образом, Linux изолирует приложения друг от друга и от системы.

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

Подписание приложений

Все APK-файлы должны быть подписаны сертификатом, закрытый ключ которого хранится у разработчика. Сертификат не обязательно должен быть подписан центром сертификации. Использование самоподписанных сертификатов допустимо и является типичным для приложений Android. Цель сертификатов в Android — различать авторов приложений. Это позволяет системе предоставлять или запрещать приложениям доступ к разрешениям уровня подписи , а также разрешать или запрещать запросы приложений на получение той же идентификационной информации Linux, что и у других приложений.

Предоставить разрешения на подпись после изготовления устройства

Начиная с Android 12 (уровень API 31), атрибут knownCerts для разрешений на уровне подписи позволяет ссылаться на дайджесты известных сертификатов подписи во время объявления.

Вы можете объявить атрибут knownCerts и использовать флаг knownSigner в атрибуте protectionLevel вашего приложения для определённого разрешения на уровне подписи. Затем система предоставит это разрешение запрашивающему приложению, если любой подписант в его родословной, включая текущего, соответствует одному из дайджестов, объявленных с разрешением в атрибуте knownCerts .

Флаг knownSigner позволяет устройствам и приложениям предоставлять разрешения на подпись другим приложениям без необходимости подписывать приложения во время производства и отправки устройства.

Идентификаторы пользователей и доступ к файлам

Во время установки Android присваивает каждому пакету уникальный идентификатор пользователя Linux. Этот идентификатор остаётся неизменным на протяжении всего срока службы пакета на данном устройстве. На другом устройстве тот же пакет может иметь другой UID — важно то, что каждый пакет имеет уникальный UID на данном устройстве.

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

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

Дополнительную информацию о модели безопасности Android см. в разделе Обзор безопасности Android .

Определение и обеспечение соблюдения разрешений

Чтобы обеспечить соблюдение собственных разрешений, необходимо сначала объявить их в файле AndroidManifest.xml используя один или несколько элементов <permission> .

Соглашение об именовании

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

Мы рекомендуем добавлять к разрешениям префикс в виде имени пакета приложения, используя обратный доменный стиль именования, после которого следует .permission. , а затем описание возможности, которую представляет разрешение, в верхнем регистре SNAKE_CASE. Например, com.example.myapp.permission.ENGAGE_HYPERSPACE .

Соблюдение этой рекомендации позволяет избежать конфликтов имен и помогает четко определить владельца и цель пользовательского разрешения.

Пример

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

<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.myapp" >
    
    <permission
      android:name="com.example.myapp.permission.DEADLY_ACTIVITY"
      android:label="@string/permlab_deadlyActivity"
      android:description="@string/permdesc_deadlyActivity"
      android:permissionGroup="android.permission-group.COST_MONEY"
      android:protectionLevel="dangerous" />
    ...
</manifest>

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

Атрибут android:permissionGroup необязателен и используется только для того, чтобы система могла отображать разрешения пользователю. В большинстве случаев для него задаётся стандартная системная группа (указанная в android.Manifest.permission_group ), хотя вы можете определить группу самостоятельно, как описано в следующем разделе. Мы рекомендуем использовать существующую группу, поскольку это упрощает интерфейс разрешений, отображаемый пользователю.

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

Вот пример метки и описания для разрешения CALL_PHONE :

<string name="permlab_callPhone">directly call phone numbers</string>
<string name="permdesc_callPhone">Allows the app to call non-emergency
phone numbers without your intervention. Malicious apps may cause unexpected
calls on your phone bill.</string>

Создать группу разрешений

Как показано в предыдущем разделе, вы можете использовать атрибут android:permissionGroup , чтобы помочь системе описать разрешения пользователю. В большинстве случаев вы указываете стандартную системную группу (указанную в android.Manifest.permission_group ), но вы также можете определить свою собственную группу с помощью <permission-group> .

Элемент <permission-group> определяет метку для набора разрешений — как объявленных в манифесте с помощью элементов <permission> , так и объявленных в других местах. Это влияет только на то, как разрешения группируются при представлении пользователю. Элемент <permission-group> не определяет разрешения, принадлежащие группе, но задаёт ей имя.

Вы можете разместить разрешение в группе, назначив имя группы атрибуту permissionGroup элемента <permission> .

Элемент <permission-tree> объявляет пространство имен для группы разрешений, определенных в коде.

Рекомендации по пользовательским разрешениям

Вы можете определить индивидуальные разрешения для своих приложений и запросить их у других приложений, определив элементы <uses-permission> . Однако тщательно оцените необходимость этого.

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

If a custom permission is necessary, consider whether only applications signed by the same developer as the application performing the permission check need to access it—such as when implementing secure interprocess communications between two applications from the same developer. If so, we recommend using signature permissions . Signature permissions are transparent to the user and avoid user-confirmed permissions, which can be confusing to users.

Продолжайте читать о:

<uses-permission>
Ссылка API для тега манифеста, в котором указаны требуемые системные разрешения для вашего приложения.

Вас также может заинтересовать:

Обзор безопасности Android
Подробное обсуждение модели безопасности платформы Android.