2012-01-11 51 views
52

我有两个应用程序。如何在Android中使用自定义权限?

一种是声明许可和具有单Activity

部分

的AndroidManifest.xml

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:permission="your.namespace.permission.TEST" > 
    <activity 
     android:name=".DeclaringPermissionActivity" 
     android:label="@string/app_name" > 

     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 

     <intent-filter> 
     <action android:name="android.intent.action.VIEW" /> 
     <category android:name="android.intent.category.DEFAULT" /> 
     <category android:name="android.intent.category.BROWSABLE" /> 
     <data android:scheme="myapp" 
      android:host="myapp.mycompany.com" /> 
     </intent-filter> 
    </activity> 
</application> 

第二声明了使用许可

部分

的AndroidManifest.xml

<uses-sdk android:minSdkVersion="10" /> 
<uses-permission android:name="your.namespace.permission.TEST" /> 

<application 

Activity部分:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("myapp://myapp.mycompany.com/index"))); 
} 

我安装的应用程序,宣布允许的话,我跑第二个应用程序。

在结果我得到安全例外:

01-11 09:46:55.249: E/AndroidRuntime(347): java.lang.RuntimeException: Unable to start activity ComponentInfo{your.namespace2/your.namespace2.UsingPErmissionActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.VIEW dat=myapp://myapp.mycompany.com/index cmp=your.namespace/.DeclaringPermissionActivity } from ProcessRecord{407842c0 347:your.namespace2/10082} (pid=347, uid=10082) requires your.namespace.permission.TEST 
+0

我只想指出这个漏洞:http://commonsware.com/blog/2014/02/12/vulnerabilities-custom-permissions.html – Tobrun 2014-09-05 11:08:21

+0

关于上面的漏洞评论,请注意Android 5.0中的更改地址这个问题:http://developer.android.com/about/versions/android-5.0-changes.html#custom_permissions – Nonos 2015-03-17 14:06:47

回答

98

我创建了一个测试代码,你可以用它和测试权限。有两个应用程序PermissionTestClient使用此权限声明权限并保护其活动。这里是它的清单文件:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.testpackage.permissiontestclient" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk android:minSdkVersion="10" /> 
    <permission android:name="com.testpackage.mypermission" android:label="my_permission" android:protectionLevel="dangerous"></permission> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:permission="com.testpackage.mypermission" 
      android:name=".PermissionTestClientActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 

      <intent-filter > 
       <action android:name="com.testpackage.permissiontestclient.MyAction" /> 
       <category android:name="android.intent.category.DEFAULT" />     
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

Activity文件没有什么特别之处,所以我不会在这里显示它。

PermissionTestServer应用程序从PermissionTestClient调用活动。下面是它的manifest文件:

<?xml version="1.0" encoding="utf-8"?> 

<uses-sdk android:minSdkVersion="10" /> 
<uses-permission android:name="com.testpackage.mypermission"/> 

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 
    <activity 
     android:name=".PermissionTestServerActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

</manifest> 

而且活动时间:

package com.testpackage.permissiontestserver; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 

public class PermissionTestServerActivity extends Activity { 
    private static final String TAG = "PermissionTestServerActivity"; 

    /** Called when the activity is first created. */ 
    Button btnTest; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     btnTest = (Button) findViewById(R.id.btnTest); 
     btnTest.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Log.d(TAG, "Button pressed!"); 
       Intent in = new Intent(); 
       in.setAction("com.testpackage.permissiontestclient.MyAction"); 
       in.addCategory("android.intent.category.DEFAULT"); 
       startActivity(in); 
      } 
     }); 
    } 
} 

为了测试它只是从服务器应用程序中删除的使用许可权。你会得到安全违规错误。

+2

谢谢,我的错误是将'permission'属性仅限于''元素。 – pixel 2012-01-11 09:56:35

+0

当我在PermissionTestClient中使用android:protectionLevel =“signature”时,这不起作用,我使用该应用启动器的权限并获得:Permission Denial:启动Intent {act = android。intent.action.MAIN cat = [android.intent.category.LAUNCHER] flg = 0x10000000 cmp = my.package.foobar/.DashboardActivity} from null(pid = 4070,uid = 2000)require my.custom.permission.ACCESS_ACTIVITY - 因此该应用程序无法启动它自己的活动0_o – fr1550n 2013-06-27 08:54:43

+2

签名级别的权限意味着您的客户端和服务器应使用相同的证书进行签名。尝试使用危险级别启动代码,如果一切正常,然后尝试使用签名启动。还有一件事,如果你使用签名,我认为你需要导出一个签名的apk文件,然后安装它们。 – Yury 2013-06-28 07:24:16

29

您需要通过专门 宣布它来创建您的基本应用清单权限。例如:

<permission android:name="your.namespace.permission.TEST" 
    android:protectionLevel="normal" android:label="This is my custom permission" /> 

后来利用它在您需要的应​​用程序为:

<uses-permission android:name="your.namespace.permission.TEST" /> 

注:至关重要的是要保持你的自定义权限安装应用程序的顺序。即您必须安装该应用程序第一个它声明权限并稍后安装使用它的那个。此顺序中的任何中断可能会破坏习惯用法。权限。

+0

简洁而简短,它的工作原理。顶级投票答案更好,但这正是问题中提出的问题。请注意,这是您需要使用自定义权限的全部因素,因为安全管理员负责处理其余部分。 – PSIXO 2014-08-04 14:41:27

+0

即使我在创建权限的应用程序中声明使用权限,我也无法使其工作。它在启动时引发安全异常 – Anshu 2014-12-23 12:42:46

+1

只要我没有记错,安装应用程序的顺序也很重要。首先安装声明自定义权限的应用程序,然后安装使用该自定义权限的应用程序。 – waqaslam 2014-12-23 12:48:05

1

正如答案中所述,您还应该考虑安装应用程序的顺序。

这是重要的,因为:

如果定义权限(应用程序A)的应用程序之前,已安装的请求许可的应用程序(应用程序B),则会有在特定的设备没有这样的定义的权限所以操作系统根本不会要求许可。

后来,当您安装应用程序A并尝试运行应用程序B时,后者将无法访问安全组件。

一种解决方法是定义相同的自定义权限在这两个应用程序,A和B,以确保该许可在该设备存在无论哪个应用程序首次安装,所以当安装了应用程序A,则允许将已发到App B.

在这种情况下,虽然,你应该确保在保护水平是双方的声明相同,因为这可能导致安全风险

(请注意,从android 5.0开始,您不能在多个应用中定义相同的权限,除非这些应用使用相同的签名密钥签名)。