Content Provider的权限

Content Provider的权限的管理很复杂,所以需要慢慢的说。

 
一个Provider里面可能有私有数据,也有公有数据。也就是说,有可能有些数据可以公开,有些不能公开。并且,有些数据可以让别人修改,有些不能让别人修改。
 
围绕上诉的可能情况,Provider就需要设置读权限(android:readPermission),和写权限(android:writePermission),或者干脆都设置(android:permission)。因为一个Provider可能被多个程序共同调用,那么这个Provider的数据,就需要做同步处理,因此需要设置android:multiprocess="true"
 
那么怎么控制哪些数据是可以操作的,哪些又是不能操作的呢?Provider是通过URI来识别需要操作的数据是什么,因此数据的限制就需要体现在对URI的控制上。
 
path-permission,控制访问在这个路径下的数据的权限,如:
<path-permission android:pathPrefix="/users"            
    android:permission="lichie.provider.permission"/>    
意思就是,访问“/users”这个路径下的数据,必须要有"lichie.provider.permission"的权限。
值得注意的是:如果provider没有设置权限,只设置了path-permission的权限,那么在android 2.3.3版本中,path-permission设置的权限,是不会生效的。
 
<provider
    android:name=".PackageProvider"
    android:authorities="com.ygomi.packageprovider"
    android:multiprocess="true"
    android:readPermission="com.ygomi.packageprovider.permission.read">
    <path-permission
        android:pathPattern="/apks/.*"
        android:permission="com.ygomi.packageprovider.permission.application.read"/>
</provider>

这段代码的path-permission是有效的,但是下面这段代码是无效的。

<provider
    android:name=".PackageProvider"
    android:authorities="com.ygomi.packageprovider"
    android:multiprocess="true">
    <path-permission
        android:pathPattern="/apks/.*"
        android:permission="com.ygomi.packageprovider.permission.application.read"/>
</provider>
android:grantUriPermissions,管理哪个范围的数据权限需要处理。这个属性其实不用显示的设置,因为如果设置了android:readPermission, android:writePermission ,android:permission中的任意一个android:grantUriPermissions就默认是true了;如果设置了grant-uri-permission,那么android:grantUriPermissions默认就是false;如果都设置了,那么android:grantUriPermissions也是false。
 
grant-uri-permission这个东西是非常难理解了。文档上虽然说是在没有权限的程序,需要访问Provider的时候,用于绕过权限控制的。但是这个东西第一次使用,还是非常的难。下面来细说一下。
 
首先,要建立一个观念,没有权限,就一定不能访问,否则就有安全隐患。我们来举个例子:
应用程序(Application)A有一个Provider来提供一些数据给其他程序访问,但是他需要设置一个权限控制,所以在应用程序A的配置文件中,就有了下面一段代码:
<provider
    android:name=".MyProvider"
    android:authorities="mytest.testProvider"
    android:multiprocess="true"
    android:readPermission="lichie.provider.permission">
    <grant-uri-permission android:pathPrefix="/user/"/>
</provider>
意思就是,除了应用程序A外,其他所有的程序,都必须具有"lichie.provider.permission"的权限,才能访问Provider的数据。但是允许大家在没有权限的时候,通过"/user/"访问。等等,等等,没有权限也可以用“/user/”访问,那么要权限来有啥子用啦?
 
精彩的地方来了,其实grant-uri-permission的作用是使,调用Provider的程序(我们这里叫应用程序B)可以没有权限,但是调用应用程序B的程序(我们这里叫应用程序C),必须要有权限。
 
所以,在应用程序C的配置文件中,需要有以下代码:
<uses-permission android:name="lichie.provider.permission" />

 

一个content provider可能想保护它的读写权限,而同时与它对应的直属客户端也需要将特定的URI传递给其它应用程序,以便其它应用程序对该URI进行操作。一个典型的例子就是邮件程序处理带有附件的邮件。进入邮件需要使用permission来保护,因为这些是敏感的用户数据。然而,如果有一个指向图片附件的URI需要传递给图片浏览器,那个图片浏览器是不会有访问附件的权利的,因为他不可能拥有所有的邮件的访问权限。
针对这个问题的解决方案就是per-URI permission:当启动一个activity或者给一个activity返回结果的时候,呼叫方可以设置Intent.FLAG_GRANT_READ_URI_PERMISSION和/或 Intent.FLAG_GRANT_WRITE_URI_PERMISSION . 这会使接收该intent的activity获取到进入该Intent指定的URI的权限,而不论它是否有权限进入该intent对应的content provider。


这种机制允许一个通常的capability-style模型,这种模型是以用户交互(如打开一个附件, 从列表中选择一个联系人)为驱动,特别获取fine-grained permissions(更细粒化的权限)。这是一种减少不必要权限的重要方式,这种方式主要针对的就是那些和程序的行为直接相关的权限。
这些URI permission的获取需要content provider(包含那些URI)的配合。强烈推荐在content provider中提供这种能力,并通过android:grantUriPermissions或者<grant-uri-permissions>标签来声明支持。

<grant-uri-permission android:path="string"
                      android:pathPattern="string"
                      android:pathPrefix="string" />

 

posted @ 2016-11-05 14:29  编程小爬虫  阅读(2300)  评论(0编辑  收藏  举报