2010-11-14 8 views
5

Ho problemi a concedere "autorizzazioni inverse" per le app che I desiderano fornire con dati sensibili in modo controllato.Qual è la corretta gestione delle autorizzazioni quando si inviano dati sensibili per le app come allegato e-mail?

La mia domanda è un tracker tempo e, perché il registro di tempo-tracking potrebbe essere considerato informazioni personali, ho creato un permesso per l'accesso e assegnato il android.permission- group.PERSONAL_INFO gruppo di autorizzazioni.

Per esportare il registro ora dal telefono, aggiungo la possibilità di inviare il registro come allegato di posta elettronica. L'allegato è generato da un provider di contenuti protetto dalla mia autorizzazione appena aggiunta. Il mio codice per l'invio della posta elettronica è simile al seguente:

String email = "[email protected]"; 
    Uri uri = TimeLog.CSVAttachment.CONTENT_URI; 
    Intent i = new Intent(Intent.ACTION_SEND, uri); 
    i.setType("text/csv"); 
    i.putExtra(Intent.EXTRA_EMAIL, new String[]{email}); 
    i.putExtra(Intent.EXTRA_SUBJECT, "Time log"); 
    i.putExtra(Intent.EXTRA_TEXT, "Hello World!"); 
    i.putExtra(Intent.EXTRA_STREAM, uri); 
    i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
    startActivity(i); 

Quando si esegue sul mio telefono HTC, ho una scelta pop-up tra Gmail e la posta HTC. La scelta di Gmail, ottengo questa eccezione in Gmail:

ERROR/AndroidRuntime(8169): Caused by: java.lang.SecurityException: 
Permission Denial: reading com.mycompany.timelog.TimeLog uri 
content://com.mycompany.timelog/csv_attachment from pid=8169, 
uid=10035 requires com.mycompany.timelog.permission.READ_TIME_LOG 

io ho android:grantUriPermissions="true" set sul mio fornitore, ma che non sta aiutando. Ho una teoria sul perché questo accade. Ho avuto atteso FLAG_GRANT_READ_URI_PERMISSION per dare a Gmail il diritto di accesso il mio fornitore di contenuti, ma credo che ciò che realmente accade è che questa autorizzazione viene concessa per com.android.internal.app.ResolverActivity perché non v'è più di una corrispondenza per Intent e Android creano un'attività wrapper per visualizzando la scelta per l'utente.

Così, ho provato codificare questo nella mia app solo per le prove:

grantUriPermission("com.google.android.gm", uri, 
     Intent.FLAG_GRANT_READ_URI_PERMISSION); 

Questo permette di Gmail per visualizzare la posta elettronica in modo corretto e che può premere "Send". Purtroppo, dopo GMail ha chiuso ottengo questa eccezione in com.google.process.gapps:

ERRORE/AndroidRuntime (7617): java.lang.SecurityException: Permesso Denial: lettura com.mycompany.timelog.TimeLog uri contenuti: //com.mycompany.timelog/csv_attachment da pid = 7617, uid = 10011 richiede com.mycompany.timelog.permission.READ_TIME_LOG

si noti che questo viene da un diverso PID e UID. Questo perché la chiamata effettiva a openAssetFile avviene da qualche componente del provider di sincronizzazione appartenente a un altro pacchetto (com.google.android.googleapps?).

Mentre ho avuto qualche speranza di finalmente trovare un modo per concedere le autorizzazioni al destinatario finale del mio ACTION_SEND intenti, il fatto che la chiamata a openAssetFile accade da qualche praticamente pacchetto non correlato completamente diverso e mi lascia sconcertato da come il permesso di concessione è dovrebbe funzionare.

Quindi, in definitiva, la mia domanda è, dato che il registro è dati sensibili, come consentirei che venga inviato via email come allegato, rispettando la privacy dell'utente (ad es.senza rendere leggibile il mondo degli allegati )?

+0

Cosa intendi per "rendere leggibile il mondo degli allegati"? –

+0

Voglio dire non limitarlo a permessi specifici, quindi consentire a qualsiasi app di accedere all'URI. O, per esempio, mettendolo sulla scheda SD. – flodin

+1

Grande uso delle autorizzazioni. Anche se sarebbe possibile (per il destinatario) utilizzare la crittografia a chiave pubblica per crittografare prima l'allegato e-mail prima che lasci il proprio fornitore di contenuti? O costruisci la possibilità di inviare l'email direttamente dalla tua app? –

risposta

3

Cari persone dal futuro,

Sembra anche Google si risolve questo problema in un altro modo, che sono incappato durante il tentativo di risolvere lo stesso problema.

Se si guarda al com.android.contacts.detail.ContactLoaderFragment a trovare nel metodo private Uri getPreAuthorizedUri(Uri uri):

mContext.getContentResolver().call(
      ContactsContract.AUTHORITY_URI, 
      ContactsContract.Authorization.AUTHORIZATION_METHOD, 
      null, 
      uriBundle); 

che si risolve a com.android.providers.contacts.ContactsProvider2 dove un metodo simile call aggiungere l'URI a una mappa mPreAuthorizedUris che viene utilizzato nelle query/update/... -metodi.

Il valore di ritorno di tale chiamata viene inserito nell'Intent e quindi utilizzato.

+0

Grazie, questa sembra una soluzione intelligente. Genera un cookie crittograficamente sicuro con una ragionevole scadenza e lo passa all'app di posta elettronica. – flodin

0

I dati della tua app non sono accessibili ad altre app. Basta usare un archivio privato. Avete diverse opzioni:

  1. Sava timetracking dati al database. Il database dell'app è visibile solo all'app che lo ha creato. Altre app non saranno in grado di vedere questi dati. Quando si invia un messaggio di posta elettronica basta interrogare il database e creare un allegato di testo.

  2. Creare un file privato tramite Context.openFileOutput().

+0

Non penso che tu abbia capito la domanda perché mi stai dicendo di fare quello che sto già facendo. Il problema è che l'allegato di testo diventa accessibile a qualsiasi app sul telefono, quindi è un buco di sicurezza. – flodin

+0

In che modo un allegato è diventato disponibile per qualsiasi app? Afaik, è accessibile solo dall'app che lo ha creato (il tuo) e dall'app di posta elettronica scelta dall'utente. Mi sto perdendo qualcosa qui? –

+0

Beh, sì, se creo un file privato con Context.openFileOutput(), l'app di posta elettronica non sarà in grado di leggerlo.Se, invece, utilizzo il flag MODE_WORLD_READABLE, ogni app sul telefono sarà in grado di leggerla. Ho bisogno di un modo per limitare l'accesso in modo che solo l'app di posta elettronica possa accedervi. – flodin

1

Questo è un approccio piacevole, purtroppo, come si sta vedendo probabilmente ci sono un certo numero di questioni sarà eseguito in al quadro che ti impediscono di farlo. Ci sono attualmente alcuni problemi con la concessione di permessi uri che rendono quella funzionalità meno utile di quanto dovrebbe essere (molti di questi saranno indirizzati in Gingerbread), e per di più Gmail non sembra aspettarsi che ciò accada e si occupi di mantenere il permesso concesso finché ne ha bisogno.

Quanto sono grandi questi dati? Se non è troppo grande, che ne pensi di includerlo nella stringa Intent come intestazione?

+0

Con una stima di dieci anni di utilizzo con 10 voci al giorno, direi circa 1 o 2 MB di dati. Qual è la dimensione massima di un intento? Credi che quello che descriverò sarà possibile fare sul pan di zenzero? – flodin

+0

Come ritaglio principale,> 256K è troppo grande. Sospetto che ciò non sia ancora possibile in GB, perché probabilmente l'app non sarà ancora in grado di gestire la ricezione di questa intenzione quando ha solo temporaneamente il permesso di accedere ai dati. Sospetto che la maggior parte delle altre app di posta elettronica non lo gestiranno. – hackbod

+1

È davvero probabile che l'utente esporti dieci anni di dieci voci al giorno contemporaneamente? Sono sicuro che questo problema di autorizzazioni sarà risolto in dieci anni;) In alternativa, non è probabile che i dati di questo tempo siano altamente comprimibili e potresti allegare un file .gz o .zip piuttosto che un .csv? –

Problemi correlati