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的配置文件中,就有了下面一段代码:
意思就是,除了应用程序A外,其他所有的程序,都必须具有"lichie.provider.permission"的权限,才能访问Provider的数据。但是允许大家在没有权限的时候,通过"/user/"访问。等等,等等,没有权限也可以用“/user/”访问,那么要权限来有啥子用啦?
精彩的地方来了,其实
grant-uri-permission的作用是使,调用Provider的程序(我们这里叫应用程序B)可以没有权限,但是调用应用程序B的程序(我们这里叫应用程序C),必须要有权限。
所以,在应用程序C的配置文件中,需要有以下代码: