Benutzerdefinierte App-Berechtigung festlegen

In diesem Dokument wird beschrieben, wie App-Entwickler die von Android bereitgestellten Sicherheitsfunktionen verwenden können, um eigene Berechtigungen zu definieren. Durch die Definition benutzerdefinierter Berechtigungen kann eine App ihre Ressourcen und Funktionen mit anderen Apps teilen. Weitere Informationen zu Berechtigungen finden Sie in der Übersicht über Berechtigungen.

Hintergrund

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

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 sind, die mit demselben Zertifikat signiert sind.

App-Signatur

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

Signaturberechtigungen nach der Geräteherstellung gewähren

Ab Android 12 (API-Level 31) können Sie mit dem Attribut knownCerts für Berechtigungen auf Signaturniveau bei der Deklaration auf die Digests 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 Signaturstufe verwenden. Anschließend gewährt das System diese Berechtigung einer anfragenden App, wenn ein Signierer in der Signaturherkunft der anfragenden App, einschließlich des aktuellen Signierers, mit einem der Digests übereinstimmt, die mit der Berechtigung im Attribut knownCerts deklariert sind.

Mit dem Flag knownSigner können Geräte und Apps anderen Apps Signaturberechtigungen gewähren, ohne dass die Apps zum Zeitpunkt der Geräteherstellung und des Versands 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 für die Dauer 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 Sicherheitsmaßnahmen auf Prozessebene erfolgen, 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 Nutzer-ID dieser App zugewiesen. Andere Pakete können normalerweise nicht darauf zugreifen.

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

Berechtigungen definieren und erzwingen

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

Namenskonvention

Das System lässt nicht zu, 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 den Paketnamen einer App voranzustellen. Verwenden Sie dazu die Benennung im Reverse-Domain-Stil, gefolgt von .permission. und dann einer Beschreibung der Funktion, die die Berechtigung darstellt, in SNAKE_CASE in Großbuchstaben. Beispiel: com.example.myapp.permission.ENGAGE_HYPERSPACE

Wenn Sie dieser Empfehlung folgen, vermeiden Sie Namenskonflikte und können den Inhaber und die Absicht einer benutzerdefinierten Berechtigung klar identifizieren.

Beispiel

Eine App, die steuern muss, welche anderen Apps eine ihrer Aktivitäten starten können, kann beispielsweise so eine Berechtigung für diesen Vorgang 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 von Apps, die die Berechtigung benötigen, informiert werden sollen oder welche Apps die Berechtigung haben können, wie in der verlinkten Dokumentation beschrieben.

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

Sie müssen sowohl ein Label als auch eine Beschreibung für die Berechtigung angeben. Dies sind String-Ressourcen, die der Nutzer sehen kann, wenn er eine Liste von Berechtigungen (android:label) oder Details zu einer einzelnen Berechtigung (android:description) aufruft. Das Label ist kurz und beschreibt in wenigen Worten die wichtigste Funktion, die durch die Berechtigung geschützt wird. Die Beschreibung besteht aus ein paar Sätzen, die beschreiben, was der Inhaber mit der Berechtigung tun kann. Unsere Konvention ist eine Beschreibung mit zwei Sätzen, wobei der erste Satz die Berechtigung beschreibt und der zweite Satz den Nutzer vor den Dingen warnt, die schiefgehen können, wenn einer App die Berechtigung gewährt wird.

Hier ist 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, dem Nutzer Berechtigungen zu beschreiben. In den meisten Fällen legen Sie hier eine Standardsystemgruppe fest (aufgeführt in android.Manifest.permission_group). Sie können aber auch mit <permission-group> eine eigene Gruppe definieren.

Mit dem <permission-group>-Element wird ein Label für eine Reihe von Berechtigungen definiert, die sowohl im Manifest mit <permission>-Elementen als auch an anderer Stelle deklariert sind. Dies wirkt sich nur darauf aus, wie die Berechtigungen gruppiert werden, wenn sie dem Nutzer angezeigt 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 den Gruppennamen dem Attribut permissionGroup des Elements <permission> zuweisen.

Das Element <permission-tree> deklariert einen Namespace für eine Gruppe von Berechtigungen, die im Code definiert sind.

Benutzerdefinierte Berechtigungsempfehlungen

Du kannst benutzerdefinierte Berechtigungen für deine Apps definieren und benutzerdefinierte Berechtigungen von anderen Apps anfordern, indem du <uses-permission>-Elemente definierst. Prüfen Sie jedoch sorgfältig, ob dies erforderlich ist.

  • Wenn du eine Suite von Apps entwirfst, die sich gegenseitig Funktionen zur Verfügung stellen, solltest du die Apps so entwerfen, dass jede Berechtigung nur einmal definiert wird. Das ist erforderlich, wenn die Apps nicht alle mit demselben Zertifikat signiert sind. Auch wenn alle Apps mit demselben Zertifikat signiert sind, empfiehlt es sich, jede Berechtigung nur einmal zu definieren.
  • Wenn die Funktion nur für Apps verfügbar ist, die mit derselben Signatur wie die bereitstellende App signiert sind, kannst du die Definition benutzerdefinierter Berechtigungen möglicherweise vermeiden, indem du Signaturprüfungen verwendest. 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 die Anfrage erfüllt.

Wenn eine benutzerdefinierte Berechtigung erforderlich ist, sollten Sie überlegen, ob nur Anwendungen, die vom selben Entwickler wie die Anwendung signiert wurden, die die Berechtigungsprüfung durchführt, darauf zugreifen müssen – z. B. bei der Implementierung einer sicheren Interprocess Communication zwischen zwei Anwendungen desselben Entwicklers. In diesem Fall empfehlen wir die Verwendung von Signaturberechtigungen. Signaturberechtigungen sind für den Nutzer transparent und vermeiden vom Nutzer bestätigte Berechtigungen, die für Nutzer verwirrend sein können.

Weitere Informationen:

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

Folgendes könnte Sie auch interessieren:

Sicherheit bei Android
Eine detaillierte Beschreibung des Sicherheitsmodells der Android-Plattform.