代码之家  ›  专栏  ›  技术社区  ›  flodin

将敏感应用程序数据作为电子邮件附件发送时,正确的权限处理是什么?

  •  6
  • flodin  · 技术社区  · 14 年前

    我无法为我的应用程序授予“反向权限” 希望以受控方式提供敏感数据。

    我的应用程序是一个时间跟踪程序,因为时间跟踪日志 可以认为是个人信息,我已经创建了一个权限 访问它并赋予它android.permission- 组。个人信息权限组。

    要从手机导出时间日志,我正在添加发送功能 日志作为电子邮件附件。附件由 受我新添加的权限保护的内容提供程序。我的 发送电子邮件的代码如下所示:

       String email = "someone@example.com";
       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);
    

    在我的HTC手机上运行时,我可以在Gmail中选择 还有HTC邮件。选择Gmail,我在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
    

    我确实有 android:grantUriPermissions="true" 设置在我的提供商上,但是 那没用。我有个理论解释为什么会这样。我有 需要FLAG_GRANT_READ_URI_权限才能授予Gmail 访问我的内容提供商,但我认为真正发生的是 此权限授予 com.android.internal.app.ResolverActivity,因为 一个匹配的意图和Android创建一个包装器活动 向用户显示选择。

    所以,我试着将它硬编码到我的应用程序中只是为了测试:

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

    这允许Gmail正确显示电子邮件,我可以按 “发送”。不幸的是,GMail关闭后,我得到了这个异常 网址:com.google.process.gapps:

    ERROR/AndroidRuntime(7617):java.lang.SecurityException:权限 拒绝:正在读取com.mycompany.timelog.timelog uri content://com.mycompany.timelog/csv_附件,来自pid=7617, uid=10011需要 com.mycompany.timelog.permission.READ_TIME_LOG

    注意,这来自不同的PID和UID。这是因为 对openAssetFile的实际调用来自某个同步提供程序 属于不同包的组件 (com.google.android.googleapps?).

    虽然我有希望最终找到一种方法来授予权限 给我的最终接受者 ACTION_SEND 意图,事实上 openAssetFile发生在一些完全不同的 不相关的软件包让我对许可的授予方式感到困惑 应该有用的。

    所以最终我的问题是,如果日志是敏感数据, 我如何允许它作为附件通过电子邮件发送,同时尊重 用户的隐私(例如,不创建附件世界 可读吗?

    3 回复  |  直到 12 年前
        1
  •  4
  •   Steven Verborgh    13 年前

    亲爱的未来人,

    似乎连谷歌自己也以另一种方式解决了这个问题,这是我在试图解决这个问题时偶然发现的。

    如果你看看 com.android.contacts.detail.ContactLoaderFragment 你在方法中发现 private Uri getPreAuthorizedUri(Uri uri) :

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

    决定 com.android.providers.contacts.ContactsProvider2 其中 call 方法将uri添加到映射 mPreAuthorizedUris 用于 query/update/... -方法。

    调用的返回值放在意图中,然后使用。

        2
  •  1
  •   hackbod    14 年前

    这是一个很好的方法,不幸的是,正如您所看到的,在框架中可能会遇到一些问题,阻止您这样做。目前,在授予uri权限方面存在一些问题,使得该功能不如预期的那么有用(其中许多问题将在姜饼中解决),而在Gmail之上,似乎并不指望会发生这种情况,只要需要,就可以保留授予的权限。

    这个数据有多大?如果它不是太大,那么将它作为字符串包含在意图中如何?

        3
  •  0
  •   Peter Knego    14 年前

    其他应用无法访问你的应用的数据。只需使用专用存储器。你有几个选择:

    1. Sava时间跟踪数据到数据库。应用程序数据库仅对创建它的应用程序可见。其他应用程序将无法查看此数据。发送电子邮件时,只需查询数据库并创建文本附件。

    2. 通过创建私有文件 Context.openFileOutput() .