Android中的权限管理(基于Permission ProtectionLevel)

1、什么是protectionlevel呢?

我们经常在AndroidManifest中使用权限,如果我们想让应用程序可以发短信,那么应该这样写:

 <uses-permission android:name="android.permission.SEND_SMS" />

那么这个权限的定义是在哪里定义的呢?如下:

frameworks/base/core/res/AndroidManifest.xml

<permission android:name="android.permission.SEND_SMS"
        android:permissionGroup="android.permission-group.COST_MONEY"
        android:protectionLevel="dangerous"
        android:label="@string/permlab_sendSms"
        android:description="@string/permdesc_sendSms" />

这个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卡的权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

我们需要把Android空间的Permission Mapping到OS的GID。

我们看一个重要的类,frameworks\base\data\etc\Platform.xml

    <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
        <group gid="sdcard_rw" />
    </permission>

对于申请了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里面申请权限外,我们还可以在frameworks\base\data\etc\Platform.xml,assign权限,如下:

<assign-permission name="android.permission.WRITE_EXTERNAL_STORAGE" uid="shell" />
    <assign-permission name="android.permission.SEND_SMS" uid="shell" />
    <assign-permission name="android.permission.CALL_PHONE" uid="shell" />
    <assign-permission name="android.permission.READ_CONTACTS" uid="shell" />
    <assign-permission name="android.permission.WRITE_CONTACTS" uid="shell" />
    <assign-permission name="android.permission.READ_CALENDAR" uid="shell" />
    <assign-permission name="android.permission.WRITE_CALENDAR" uid="shell" />
    <assign-permission name="android.permission.READ_USER_DICTIONARY" uid="shell" />
    <assign-permission name="android.permission.WRITE_USER_DICTIONARY" uid="shell" />
    <assign-permission name="android.permission.ACCESS_FINE_LOCATION" uid="shell" />
    <assign-permission name="android.permission.ACCESS_COARSE_LOCATION" uid="shell" />
    <assign-permission name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" uid="shell" />
    <assign-permission name="android.permission.ACCESS_NETWORK_STATE" uid="shell" />
    <assign-permission name="android.permission.ACCESS_WIFI_STATE" uid="shell" />
    <assign-permission name="android.permission.BLUETOOTH" uid="shell" />
    <!-- System tool permissions granted to the shell. -->
    <assign-permission name="android.permission.GET_TASKS" uid="shell" />
    <assign-permission name="android.permission.CHANGE_CONFIGURATION" uid="shell" />
    <assign-permission name="android.permission.REORDER_TASKS" uid="shell" />
    <assign-permission name="android.permission.SET_ANIMATION_SCALE" uid="shell" />
    <assign-permission name="android.permission.SET_PREFERRED_APPLICATIONS" uid="shell" />
    <assign-permission name="android.permission.WRITE_SETTINGS" uid="shell" />
    <assign-permission name="android.permission.WRITE_SECURE_SETTINGS" uid="shell" />
    <assign-permission name="android.permission.BROADCAST_STICKY" uid="shell" />
    <!-- Development tool permissions granted to the shell. -->
    <assign-permission name="android.permission.SET_DEBUG_APP" uid="shell" />
    <assign-permission name="android.permission.SET_PROCESS_LIMIT" uid="shell" />
    <assign-permission name="android.permission.SET_ALWAYS_FINISH" uid="shell" />
    <assign-permission name="android.permission.DUMP" uid="shell" />
    <assign-permission name="android.permission.SIGNAL_PERSISTENT_PROCESSES" uid="shell" />
    <!-- Internal permissions granted to the shell. -->
    <assign-permission name="android.permission.FORCE_BACK" uid="shell" />
    <assign-permission name="android.permission.BATTERY_STATS" uid="shell" />
    <assign-permission name="android.permission.INTERNAL_SYSTEM_WINDOW" uid="shell" />
    <assign-permission name="android.permission.INJECT_EVENTS" uid="shell" />
    <assign-permission name="android.permission.SET_ACTIVITY_WATCHER" uid="shell" />
    <assign-permission name="android.permission.READ_INPUT_STATE" uid="shell" />
    <assign-permission name="android.permission.SET_ORIENTATION" uid="shell" />
    <assign-permission name="android.permission.INSTALL_PACKAGES" uid="shell" />
    <assign-permission name="android.permission.CLEAR_APP_USER_DATA" uid="shell" />
    <assign-permission name="android.permission.DELETE_CACHE_FILES" uid="shell" />
    <assign-permission name="android.permission.DELETE_PACKAGES" uid="shell" />
    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="shell" />
    <assign-permission name="android.permission.READ_FRAME_BUFFER" uid="shell" />
    <assign-permission name="android.permission.DEVICE_POWER" uid="shell" />
    <assign-permission name="android.permission.INSTALL_LOCATION_PROVIDER" uid="shell" />
    <assign-permission name="android.permission.BACKUP" uid="shell" />

    <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
    <assign-permission name="android.permission.ACCESS_DRM" uid="media" />
    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />

    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />

shell进程的权限我们在Android中的权限管理(基于uid gid gids setUid),已经看到过其申请的权限对应的gids。那时候没有讲shell进程是怎么样申请的这个权限,这里解决了我们的疑问。

由于platform.xml只有root用户可以操作,避免了安全问题。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-07 08:38:48

Android中的权限管理(基于Permission ProtectionLevel)的相关文章

Android中的权限管理(基于uid gid gids setUid)

我们首先来说一下传统的Linux基于uid,gid的权限管理机制: 1.用户的uid gid gids: Ubuntu操作系统当前登陆的用户是jltxgcy,那么该用户的uid为jltxgcy,gid也是jltxgcy,那么gids怎么查看呢? 答案是使用命令:cat /etc/group | grep jltxgcy.如下图: 用户的gids的名字为adm,dialout,cdrom,plugdev,lpadmin,admin,sambashare.此本分请参考linux用户组./etc/gr

Android中那些权限

Permission Permission Permission Group Permission Tree Users Permission ACCESS_CHECKIN_PROPERTIES 允许读写访问"properties"表在checkin数据库中,改值可以修改上传( Allows read/write access to the "properties" table in the checkin database, to change values th

【源码笔记】BlogEngine.Net 中的权限管理

BlogEngine.Net 是个功能点很全面的开源博客系统,容易安装和实现定制,开放接口支持TrackBack,可以定义主题配置数据源等等.可谓五脏俱全,这里先记录一下它基于Membership的权限管理(一般只说到角色就没了). Membership是.net2.0的时候就出来了,现在的最新版本是Identity(微软已经将这个Asp.net项目开源 https://github.com/aspnet/Identity ).权限管理就是处理用户.角色.和具体权限的关系.用户和角色是多对多的关

Android中使用SQLiteOpenHelper管理SD卡中的数据库

使用Android中自带的SQLiteOpenHelper可以完成数据库的创建与管理,但有两点局限: (1)数据库创建在内存卡中,大小受限,创建位置位于/data/data/应用程序名/databases中(可使用Eclispe的DDMS查看). (2)如果无法获取Root权限,则无法直接查看创建的数据库. 鉴于上述限制及实际需要,打算使用SQLiteOpenHelper管理SD卡上的数据库,通过研究SQLiteOpenHelper的源码,发现其创建或打开数据库的代码位于getWritableD

Android 中各种权限深入体验及详解

Android 中各种权限深入体验及详解 分类: Android2012-07-15 19:27 2822人阅读 评论(0) 收藏 举报 androidpermissionsinstallersystemserviceinteger 一. 权限(permission) 权限用来描述是否拥有做某件事的权力.Android系统中权限分为普通级别(Normal),危险级别(dangerous),签名级别(signature)和系统/签名级别(signature or system).系统中所有预定义的

Android 6.0 权限管理

Android 6.0 权限管理 Android permission 运行时权限(Runtime permission) 旧版兼容 6.0权限弹框的两种模式 6.0之后的权限分类 Normal permissions(普通权限) Dangerous permissions(危险权限) 运行时权限请求的基本步骤 权限请求策略 运行时权限(Runtime permission) android的权限系统一直是首要的安全概念,因为这些权限只在安装的时候被询问一次.一旦安装了,app可以在用户毫不知晓

在Android中查看和管理sqlite数据库

http://www.cnblogs.com/walkingp/archive/2011/03/28/1997437.html 在Android中查看和管理sqlite数据库 在Android中可以使用Eclipse插件DDMS来查看,也可以使用Android工具包中的adb工具来查看.android项目中的sqlite数据库位于/data/data/项目包/databases中. 使用DDMS导出sqlite数据库. 1.首先打开android项目的调试模式,然后找到显示DDMS: 选择DDM

统一身份管理中的权限管理设计

关注嘉为科技,获取运维新知 权限集中管理是统一身份管理关注的主要内容之一,由于企业应用建设的自身历程不同,权限设计与实现也必然存在差异,针对集中权限管理的设计和实现带来了不小的挑战,本文根据多年的实践经验,就统一身份管理的集中权限管理的设计与实现给予设计建议. 一 问题背景 随着信息技术和网络技术的迅猛发展,企业内部的应用系统越来越多,为此,为减少用户访问的麻烦,提升访问的便利性和体验,众多企业采用了统一身份管理的方案来解决该问题. 就企业的统一身份管理,业界提出了相应的标准,即4A标准,分别是

数据库中的grant权限赋予和系统中的权限管理是两码事。

数据库中的grant权限赋予和系统中的权限管理是两码事.grant一般是赋给个人的,对全部或单个数据库的增删改查等权限,不多说.权限管理系统 在数据库中建表,存角色,权限,不同的菜单,在java层面上写代码控制的.用filter或if等都能控制.参考资料:grant:http://www.cnblogs.com/Richardzhu/p/3318595.htmlhttp://blog.csdn.net/leshami/article/details/5688875http://7567567.b