2012-01-11 47 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開始,您不能在多個應用中定義相同的權限,除非這些應用使用相同的簽名密鑰簽名)。