Benutzerdefinierte App-Berechtigung festlegen

In diesem Dokument wird beschrieben, wie App-Entwickler die Sicherheitsfunktionen von Android verwenden können, um eigene Berechtigungen zu definieren. Durch das Definieren benutzerdefinierter Berechtigungen kann eine App ihre Ressourcen und Funktionen für andere Apps freigeben. Weitere Informationen zu Berechtigungen finden Sie in der Übersicht über Berechtigungen.

Hintergrund

Android ist ein benutzerdefiniertes Betriebssystem, in dem jede App mit einer eigenen Systemidentität (Linux-Nutzer-ID und -Gruppen-ID) ausgeführt wird. Teile des Systems werden auch in verschiedene Identitäten unterteilt. So werden Apps voneinander und vom System isoliert.

Apps können ihre Funktionen für andere Apps freigeben, indem sie Berechtigungen definieren, die andere Apps anfordern können. Sie können auch Berechtigungen definieren, die automatisch für alle anderen Apps verfügbar gemacht werden, die mit demselben Zertifikat signiert sind.

App-Signatur

Alle APKs müssen mit einem Zertifikat signiert sein, dessen privater Schlüssel vom Entwickler gehalten wird. Das Zertifikat muss nicht von einer Zertifizierungsstelle signiert sein. Es ist zulässig und üblich, dass Android-Apps selbst signierte Zertifikate verwenden. Zertifikate unter Android dienen dazu, App-Entwickler zu unterscheiden. So kann das System Apps Zugriff auf Berechtigungen auf Signaturebene gewähren oder verweigern und die Anfrage einer App, dieselbe Linux-Identität wie eine andere App zu erhalten, gewähren oder ablehnen.

Unterschriftenberechtigungen nach der Herstellung des Geräts gewähren

Ab Android 12 (API-Ebene 31) können Sie mit dem Attribut knownCerts für Berechtigungen auf Signaturebene zum Zeitpunkt der Deklaration auf die Hash-Werte bekannter Signaturzertifikate verweisen.

Sie können das Attribut knownCerts deklarieren und das Flag knownSigner im Attribut protectionLevel Ihrer App für eine bestimmte Berechtigung auf Signaturebene verwenden. Anschließend gewährt das System diese Berechtigung einer anfragenden App, wenn einer der Unterzeichner in der Signaturabfolge der anfragenden App, einschließlich des aktuellen Unterzeichners, mit einem der Digests übereinstimmt, die im Attribut knownCerts mit der Berechtigung deklariert sind.

Mit dem Flag knownSigner können Geräte und Apps anderen Apps Signaturberechtigungen gewähren, ohne dass die Apps bei der Geräteherstellung und -lieferung signiert werden müssen.

Nutzer-IDs und Dateizugriff

Bei der Installation weist Android jedem Paket eine eindeutige Linux-Nutzer-ID zu. Die Identität bleibt während der Lebensdauer des Pakets auf diesem Gerät konstant. Auf einem anderen Gerät hat dasselbe Paket möglicherweise eine andere UID. Wichtig ist, dass jedes Paket auf einem bestimmten Gerät eine eindeutige UID hat.

Da die Sicherheitsdurchsetzung auf Prozessebene erfolgt, kann der Code von zwei Paketen normalerweise nicht im selben Prozess ausgeführt werden, da sie als unterschiedliche Linux-Nutzer ausgeführt werden müssen.

Allen von einer App gespeicherten Daten wird die User-ID dieser App zugewiesen. Normalerweise können andere Pakete nicht darauf zugreifen.

Weitere Informationen zum Sicherheitsmodell von Android finden Sie unter Android-Sicherheit – Übersicht.

Berechtigungen definieren und durchsetzen

Wenn Sie Ihre eigenen Berechtigungen erzwingen möchten, müssen Sie sie zuerst in Ihrer AndroidManifest.xml mit einem oder mehreren <permission>-Elementen deklarieren.

Namenskonvention

Das System erlaubt nicht, dass mehrere Pakete eine Berechtigung mit demselben Namen deklarieren, es sei denn, alle Pakete sind mit demselben Zertifikat signiert. Wenn ein Paket eine Berechtigung deklariert, erlaubt das System dem Nutzer auch nicht, andere Pakete mit demselben Berechtigungsnamen zu installieren, es sei denn, diese Pakete sind mit demselben Zertifikat wie das erste Paket signiert.

Wir empfehlen, Berechtigungen mit dem Paketnamen einer App zu beginnen. Verwenden Sie dabei eine umgekehrte Domainbenennung, gefolgt von .permission. und dann einer Beschreibung der Funktion, die die Berechtigung darstellt, in Großbuchstaben im SNAKE_CASE-Format. Beispiel: com.example.myapp.permission.ENGAGE_HYPERSPACE.

Wenn Sie dieser Empfehlung folgen, werden Namenskollisionen vermieden und der Inhaber und die Absicht einer benutzerdefinierten Berechtigung können klar identifiziert werden.

Verwendungsbeispiele

Eine App, die steuern muss, welche anderen Apps eine ihrer Aktivitäten starten können, kann eine Berechtigung für diesen Vorgang so deklarieren:

<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>

Das Attribut protectionLevel ist erforderlich und gibt dem System an, wie Nutzer über Apps informiert werden sollen, für die die Berechtigung erforderlich ist, oder welche Apps die Berechtigung haben können, wie in der verlinkten Dokumentation beschrieben.

Das Attribut android:permissionGroup ist optional und wird nur verwendet, damit das System dem Nutzer Berechtigungen anzeigen kann. In den meisten Fällen legen Sie hier eine Standardsystemgruppe fest (in android.Manifest.permission_group aufgeführt). Sie können aber auch eine Gruppe selbst definieren, wie im folgenden Abschnitt beschrieben. Wir empfehlen, eine vorhandene Gruppe zu verwenden, da dies die Benutzeroberfläche für Berechtigungen vereinfacht.

Sie müssen sowohl ein Label als auch eine Beschreibung für die Berechtigung angeben. Dies sind Stringressourcen, die Nutzer sehen, wenn sie sich eine Liste der Berechtigungen (android:label) oder Details zu einer einzelnen Berechtigung (android:description) ansehen. Das Label ist kurz: Es beschreibt in wenigen Worten die Hauptfunktion, die durch die Berechtigung geschützt wird. Die Beschreibung besteht aus mehreren Sätzen, in denen beschrieben wird, was der Inhaber mit der Berechtigung tun kann. Wir empfehlen eine Beschreibung aus zwei Sätzen, wobei der erste Satz die Berechtigung beschreibt und der zweite Satz den Nutzer vor möglichen Risiken warnt, die sich ergeben können, wenn einer App die Berechtigung gewährt wird.

Hier ein Beispiel für ein Label und eine Beschreibung für die Berechtigung 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>

Berechtigungsgruppe erstellen

Wie im vorherigen Abschnitt gezeigt, können Sie das Attribut android:permissionGroup verwenden, um dem System zu helfen, Berechtigungen für den Nutzer zu beschreiben. In den meisten Fällen wird dies auf eine Standardsystemgruppe festgelegt (in android.Manifest.permission_group aufgeführt). Sie können aber auch mit <permission-group> eine eigene Gruppe definieren.

Das Element <permission-group> definiert ein Label für eine Reihe von Berechtigungen, sowohl für die im Manifest mit <permission>-Elementen deklarierten als auch für die an anderer Stelle deklarierten. Dies wirkt sich nur darauf aus, wie die Berechtigungen für den Nutzer gruppiert werden. Das Element <permission-group> gibt nicht die Berechtigungen an, die zur Gruppe gehören, sondern gibt der Gruppe einen Namen.

Sie können eine Berechtigung in der Gruppe platzieren, indem Sie dem permissionGroup-Attribut des <permission>-Elements den Gruppennamen zuweisen.

Mit dem Element <permission-tree> wird ein Namespace für eine Gruppe von Berechtigungen deklariert, die im Code definiert sind.

Empfehlungen für benutzerdefinierte Berechtigungen

Sie können benutzerdefinierte Berechtigungen für Ihre Apps definieren und benutzerdefinierte Berechtigungen von anderen Apps anfordern, indem Sie <uses-permission>-Elemente definieren. Überlegen Sie jedoch sorgfältig, ob dies notwendig ist.

  • Wenn Sie eine Suite von Apps entwerfen, die Funktionen füreinander freigeben, sollten Sie die Apps so gestalten, dass jede Berechtigung nur einmal definiert wird. Dies ist erforderlich, wenn die Apps nicht alle mit demselben Zertifikat signiert sind. Auch wenn die Apps alle mit demselben Zertifikat signiert sind, sollten Sie jede Berechtigung nur einmal definieren.
  • Wenn die Funktion nur für Apps verfügbar ist, die mit derselben Signatur wie die bereitstellende App signiert sind, können Sie mithilfe von Signaturprüfungen möglicherweise die Definition benutzerdefinierter Berechtigungen vermeiden. Wenn eine Ihrer Apps eine Anfrage an eine andere Ihrer Apps sendet, kann die zweite App prüfen, ob beide Apps mit demselben Zertifikat signiert sind, bevor sie der Anfrage nachkommt.

Wenn eine benutzerdefinierte Berechtigung erforderlich ist, sollten Sie überlegen, ob nur Anwendungen darauf zugreifen müssen, die vom selben Entwickler signiert wurden wie die Anwendung, die die Berechtigungsprüfung durchführt. Dies ist beispielsweise bei der Implementierung einer sicheren Inter-Process-Kommunikation zwischen zwei Anwendungen desselben Entwicklers der Fall. In diesem Fall empfehlen wir die Verwendung von Signaturberechtigungen. Unterschriftenberechtigungen sind für Nutzer transparent und es werden keine vom Nutzer bestätigten Berechtigungen verwendet, die für Nutzer verwirrend sein können.

Weitere Informationen zu:

<uses-permission>
API-Referenz für das Manifest-Tag, in dem die erforderlichen Systemberechtigungen Ihrer App deklariert werden.

Das könnte Sie auch interessieren:

Android-Sicherheit – Übersicht
Detaillierte Informationen zum Sicherheitsmodell der Android-Plattform.