Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中的權限管理(基於Permission ProtectionLevel)

Android中的權限管理(基於Permission ProtectionLevel)

編輯:關於Android編程

1、什麼是protectionlevel呢?

我們經常在AndroidManifest中使用權限,如果我們想讓應用程序可以發短信,那麼應該這樣寫:

 

 

那麼這個權限的定義是在哪裡定義的呢?如下:

 

frameworks/base/core/res/AndroidManifest.xml

 

這個xml可以認為是系統apk使用的AndroidManifest.xml,該apk使用系統的私鑰進行簽名。

 

name:權限的名字,uses-permisson使用的。

permissionGroup:權限的分類,在提示用戶安裝時會把某些功能差不多的權限放到一類。

protectionLevel:分為Normal、Dangerous、Signature、SignatureOrSystem,我們後面會著重講這個。

label:提示給用戶的權限名。

description:提示給用戶的權限描述。

 

2、protectionLevel

(1)Normal

權限被聲明為Normal級別,任何應用都可以申請,在安裝應用時,不會直接提示給用戶,點擊全部才會展示。

(2)Dangerous

權限被聲明為Dangerous級別,任何應用都可以申請,在安裝應用時,會直接提示給用戶。

(3)Signature

權限被聲明為Signature級別,只有和該apk(定義了這個權限的apk)用相同的私鑰簽名的應用才可以申請該權限。
frameworks/base/core/res/AndroidManifest.xml聲明的權限為Signature級別,那麼只有Android官方使用相同私鑰簽名的應用才可以申請該權限。

(4)SignatureOrSystem

權限被聲明為SignatureOrSystem級別,有兩種應用可以申請該權限。

1)和該apk(定義了這個權限的apk)用相同的私鑰簽名的應用

2)在/system/app目錄下的應用

 

3、舉個例子

比如百度地圖apk的AndroidManifest.xml裡面聲明了一個權限,

(1)、權限定義為Dangerous,那麼任何其他應用都可以使用。

(2)、權限定義為Signature,那麼只有使用同樣私鑰簽名的apk,例如百度網盤,可以使用這個權限。

(3)、權限定義為SignatureOrSystem,那麼使用同樣私鑰簽名的apk,例如百度網盤,可以使用這個權限。在/system/app下的應用也可以使用這個權限。

 

4、我們自然想到一個問題,申請了某個權限與否,在代碼中是怎麼控制是否可以訪問某個資源呢?

(1)、Android系統獨有的權限,在代碼中是怎麼控制是否可以訪問某個資源呢?我們看一個實際的例子。

Client端:

 

void startDockOrHome(){
	awakenDreams();
	......
}

private static void awakenDreams(){
	IDreamManager dreamManager = getDreamManager();
	if(dreamManager != null){
		try{
			dreamManager.awaken();//調用Server端的awaken
		} catch(RemoteException e){
			//fine, stay asleep then
		}
	}
Server端:

 

 

@Override // Binder call
public void awaken() {
	checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);

    final long ident = Binder.clearCallingIdentity();
    try {
        requestAwakenInternal();
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
}

private void checkPermission(String permission) {
    if (mContext.checkCallingOrSelfPermission(permission)
               != PackageManager.PERMISSION_GRANTED) {
           throw new SecurityException(Access denied to process:  + Binder.getCallingPid()
                  + , must have permission  + permission);
    }
}
Client端和Server端通過Binder進程間通信機制來通信。在Server端通過checkPermission來檢查Client端是否申明了此權限。

 

(2)、對於非Android特有的Service(底層平台已經提供,如File訪問,TCPIP數據收發等),多個入口訪問:Android API,Java API,NDK C API,shell都可以訪問。這樣權限控制就聚口在底層,所以在底層統一控制。這個底層統一控制其實就是傳統的Linux文件讀寫執行權限(rwx)。

例如在應用中申請了寫SD卡的權限:

 

我們需要把Android空間的Permission Mapping到OS的GID。

 

我們看一個重要的類,frameworksasedataetcPlatform.xml

 

    
        
    

 

/

對於申請了WRITE_EXTERNAL_STORAGE特權的應用,該應用的進程的gids就包含了sdcard_r,就可以對sd卡中的文件進行操作了。

 

再看Android_filesystem_config.h的源碼:

 

#define AID_SDCARD_RW 1015 /* external storage write access */

 

也就是說這個權限映射到1015的gid,我們再來看一張圖:

我們查看com.android.phone這個進程,該應用申請了寫外部內存卡的權限。首先使用ps查看該進程的進程號是1038,然後采用如下命令:

/

我們看到這個進程的Groups裡面有gid為1015,1015就是對應sdcard_r。

5、除了我們在AndroidManifest.xml裡面申請權限外,我們還可以在frameworksasedataetcPlatform.xml,assign權限,如下:

 


    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    
    
    

    
shell進程的權限我們在Android中的權限管理(基於uid gid gids setUid),已經看到過其申請的權限對應的gids。那時候沒有講shell進程是怎麼樣申請的這個權限,這裡解決了我們的疑問。

 

由於platform.xml只有root用戶可以操作,避免了安全問題。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved