Definisci un'autorizzazione app personalizzata

Questo documento descrive in che modo gli sviluppatori di app possono utilizzare le funzionalità di sicurezza fornite da Android per definire le proprie autorizzazioni. Con la definizione di autorizzazioni personalizzate, un'app può condividere le proprie risorse e funzionalità con altre app. Per ulteriori informazioni sulle autorizzazioni, consulta la panoramica delle autorizzazioni.

Background

Android è un sistema operativo con privilegi separati, in cui ogni app viene eseguita con un'identità di sistema distinta (ID utente e ID gruppo Linux). Le parti del sistema sono inoltre separate in identità distinte. In questo modo, Linux isola le app l'una dall'altra e dal sistema.

Le app possono esporre le proprie funzionalità ad altre app definendo le autorizzazioni che queste possono richiedere. Possono anche definire autorizzazioni che vengono messe automaticamente a disposizione di tutte le altre app firmate con lo stesso certificato.

Firma dell'app

Tutti gli APK devono essere firmati con un certificato la cui chiave privata è in possesso dello sviluppatore. Il certificato non deve essere firmato da un'autorità di certificazione. È consentito e tipico che le app per Android utilizzino certificati autofirmati. Lo scopo dei certificati in Android è distinguere gli autori delle app. In questo modo, il sistema può concedere o negare alle app l'accesso alle autorizzazioni a livello di firma e concedere o negare la richiesta di un'app di ottenere la stessa identità Linux di un'altra app.

Concedi le autorizzazioni di firma dopo la data di produzione del dispositivo

A partire da Android 12 (livello API 31), l'attributo knownCerts per le autorizzazioni a livello di firma consente di fare riferimento ai digest dei certificati di firma noti al momento della dichiarazione.

Puoi dichiarare l'attributo knownCerts e utilizzare il flag knownSigner nell'attributo protectionLevel della tua app per una determinata autorizzazione a livello di firma. Il sistema concede poi l'autorizzazione a un'app richiedente se uno dei firmatari della catena di firme dell'app richiedente, incluso il firmatario corrente, corrisponde a uno dei digest dichiarati con l'autorizzazione nell'attributo knownCerts.

Il flag knownSigner consente ai dispositivi e alle app di concedere autorizzazioni di firma ad altre app senza dover firmare le app al momento della produzione e della spedizione del dispositivo.

ID utente e accesso ai file

Al momento dell'installazione, Android assegna a ogni pacchetto un ID utente Linux distinto. L'identità rimane costante per tutta la durata del pacchetto sul dispositivo. Su un altro dispositivo, lo stesso pacchetto potrebbe avere un UID diverso. Ciò che conta è che ogni pacchetto abbia un UID distinto su un determinato dispositivo.

Poiché l'applicazione delle norme di sicurezza avviene a livello di processo, in genere il codice di due pacchetti non può essere eseguito nello stesso processo, poiché devono essere eseguiti come utenti Linux diversi.

Tutti i dati archiviati da un'app vengono assegnati all'ID utente dell'app e in genere non sono accessibili ad altri pacchetti.

Per ulteriori informazioni sul modello di sicurezza di Android, consulta la Panoramica della sicurezza Android.

Definire e applicare le autorizzazioni

Per applicare le tue autorizzazioni, devi prima dichiararle nel tuo AndroidManifest.xml utilizzando uno o più elementi <permission>.

Convenzione di denominazione

Il sistema non consente a più pacchetti di dichiarare una autorizzazione con lo stesso nome, a meno che tutti i pacchetti non siano firmati con lo stesso certificato. Se un pacchetto dichiara un'autorizzazione, il sistema non consente inoltre all'utente di installare altri pacchetti con lo stesso nome di autorizzazione, a meno che questi pacchetti non siano firmati con lo stesso certificato del primo pacchetto.

Ti consigliamo di anteporre alle autorizzazioni il nome del pacchetto di un'app, utilizzando una nomenclatura in stile dominio inverso, seguita da .permission. e da una descrizione della funzionalità rappresentata dall'autorizzazione, in SNAKE_CASE maiuscolo. Ad esempio, com.example.myapp.permission.ENGAGE_HYPERSPACE.

Se segui questo consiglio, eviti collisioni di nomi e aiuta a identificare chiaramente il proprietario e lo scopo di un'autorizzazione personalizzata.

Esempio

Ad esempio, un'app che deve controllare quali altre app possono avviare una delle sue attività può dichiarare un'autorizzazione per questa operazione come segue:

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

L'attributo protectionLevel è obbligatorio e indica al sistema come informare gli utenti delle app che richiedono l'autorizzazione o quali app possono detenere l'autorizzazione, come descritto nella documentazione collegata.

L'attributo android:permissionGroup è facoltativo e viene utilizzato solo per aiutare il sistema a mostrare le autorizzazioni all'utente. Nella maggior parte dei casi, lo imposti su un gruppo di sistema standard (elencato in android.Manifest.permission_group), anche se puoi definire un gruppo autonomamente, come descritto nella sezione seguente. Ti consigliamo di utilizzare un gruppo esistente, in quanto semplifica l'UI delle autorizzazioni mostrata all'utente.

Devi fornire sia un'etichetta che una descrizione per l'autorizzazione. Si tratta di risorse stringa che l'utente può vedere quando visualizza un elenco di autorizzazioni (android:label) o i dettagli di una singola autorizzazione (android:description). L'etichetta è breve: poche parole che descrivono la funzionalità principale protetta dall'autorizzazione. La descrizione è composta da un paio di frasi che descrivono cosa consente un'autorizzazione a un proprietario. La nostra convenzione prevede una descrizione di due frasi, dove la prima descrive l'autorizzazione e la seconda avvisa l'utente del tipo di problemi che possono verificarsi se a un'app viene concessa l'autorizzazione.

Ecco un esempio di etichetta e descrizione per l'autorizzazione 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>

Creare un gruppo di autorizzazioni

Come mostrato nella sezione precedente, puoi utilizzare l'attributo android:permissionGroup per aiutare il sistema a descrivere le autorizzazioni all'utente. Nella maggior parte dei casi, lo imposti su un gruppo di sistema standard (elencato in android.Manifest.permission_group), ma puoi anche definire un gruppo personalizzato con <permission-group>.

L'elemento <permission-group> definisce un'etichetta per un insieme di autorizzazioni, sia quelle dichiarate nel file manifest con elementi <permission> sia quelle dichiarate altrove. Questo influisce solo sul modo in cui le autorizzazioni vengono raggruppate quando vengono presentate all'utente. L'elemento <permission-group> non specifica le autorizzazioni appartenenti al gruppo, ma assegna un nome al gruppo.

Puoi inserire un'autorizzazione nel gruppo assegnando il nome del gruppo all'attributo <permission> dell'elemento permissionGroup.

L'elemento <permission-tree> dichiara uno spazio dei nomi per un gruppo di autorizzazioni definite nel codice.

Consigli sulle autorizzazioni personalizzate

Puoi definire autorizzazioni personalizzate per le tue app e richiedere autorizzazioni personalizzate da altre app definendo elementi <uses-permission>. Tuttavia, valuta attentamente se è necessario farlo.

  • Se stai progettando una suite di app che espongono funzionalità l'una all'altra, prova a progettarle in modo che ogni autorizzazione sia definita solo una volta. Devi farlo se le app non sono tutte firmate con lo stesso certificato. Anche se le app sono tutte firmate con lo stesso certificato, è buona norma definire ogni autorizzazione una sola volta.
  • Se la funzionalità è disponibile solo per le app firmate con la stessa firma dell'app che la fornisce, potresti essere in grado di evitare di definire autorizzazioni personalizzate utilizzando i controlli delle firme. Quando una delle tue app invia una richiesta a un'altra delle tue app, la seconda app può verificare che entrambe le app siano firmate con lo stesso certificato prima di soddisfare la richiesta.

Se è necessaria un'autorizzazione personalizzata, valuta se solo le applicazioni firmate dallo stesso sviluppatore dell'applicazione che esegue il controllo delle autorizzazioni devono accedere, ad esempio quando implementi comunicazioni interprocesso sicure tra due applicazioni dello stesso sviluppatore. In questo caso, ti consigliamo di utilizzare le autorizzazioni di firma. Le autorizzazioni di firma sono trasparenti per l'utente ed evitano le autorizzazioni confermate dall'utente, che possono creare confusione.

Continua a leggere per scoprire di più su:

<uses-permission>
Riferimento all'API per il tag manifest che dichiara le autorizzazioni di sistema richieste della tua app.

Potrebbero interessarti anche:

Panoramica della sicurezza di Android
Una discussione dettagliata sul modello di sicurezza della piattaforma Android.