2012-08-31 81 views
7

我没有找到一个帖子,要求与我一样的限制。限制访问内容提供商

我有一个应用程序向其他应用程序(称之为客户端应用程序)提供内容提供者(称为主应用程序)。我想限制客户端应用程序对内容提供者的访问,以便仅支持插入和可能查询方法。

我不想要什么:

  • 使内容供应商的私密,因为主要目标是提供一个数据库客户端应用程序。
  • 限制客户端应用程序的签名访问,因为任何人都必须能够编写使用主应用程序平台的客户端应用程序。

我看到的最明显的解决方案是编写两个内容提供者,一个拥有主应用程序的完全访问权限,另一个受限制的公共权限。但我认为这绝对不是一个正确的方法。

根据这个Google groups post,我想在内容提供者调用中使用Binder.getCallingUid()来检测这个调用是否来自主应用程序。所以我不能在更新删除方法,如果调用不来自主应用程序。

我怎么能得到主要应用程序UID比较?如果有可能,这个解决方案是否安全?

感谢您的建议。

+0

如果我理解正确,包含内容提供程序组件的应用程序应该是唯一具有写入权限的应用程序。那么为什么不通过Content Provider接口使用该功能呢?在这种情况下,内容提供者只会支持查询接口。 – Sameer

+0

不幸的是,客户端应用程序所需的主要访问权限是插入。所以他们也需要写访问权限。但是你是对的,主应用程序不需要使用内容提供者,但它会增加太多的复杂性和可维护性。 – FabiF

+0

好,还是一样的一点。主应用程序可以直接插入,更新和删除,而无需通过Content Provider界面。 Content Provider只提供插入和查询接口。 – Sameer

回答

8

定义像的ProtectionLevel在下面签字的权限,这个写权限将仅限于它们与相同的私钥

<permission android:name="com.yourapp.WRITE.PERMISSION" 
    android:protectionLevel="signature" 
     android:label="@string/permission_label" 
     android:description="@string/permission_desc"> 
</permission> 

<permission android:name="com.yourapp.READ.PERMISSION" 
     android:label="@string/permission_label" 
     android:description="@string/permission_desc"> 
</permission> 

然后在读取和写入权限标签ContentProvider的标签使用签名的软件。 您可以强制读取权限,或者你可以完全删除

android:readPermission="com.yourapp.READ.PERMISSION" 
android:writePermission="com.yourapp.WRITE.PERMISSION" 

所以只能由同一签名签名可以使用您的内容提供商

编辑应用程序:

也许你可以使用这个

private Collection<String> getCallingPackages() { 
    int caller = Binder.getCallingUid(); 
    if (caller == 0) { 
     return null; 
    } 
    return Lists.newArrayList(mContext.getPackageManager().getPackagesForUid(caller)); 
} 

并检查您的软件包名称是否存在于此列表中。我认为它是安全的

+0

我知道这个解决方案,但在我的情况下,客户端应用程序必须能够*插入*数据,所以他们还需要具有写入权限。 – FabiF

+0

你想限制什么?只有几个客户端应用程序通过packagename? – nandeesh

+0

如果您的应用程序需要通过sqlitedbhelper执行数据并通过contentprovider减少访问数 – nandeesh