1). Level
system <--> apps. Uid, Gid
Process <--> process Permission
Source Access per-URI-permission
2). Security Arch.
中心思想就是: 应用程序在默认情况下不可以执行对其它程序/系统/用户带来负面影响的操作;包括:RW应用私有数据,RW app files, network, wake_lock,...
一个应用程序都在自己的Sandbox中(用户ID区分),不会干扰别的应用,除非显式地声明了'permission'以获取Sandbox之外的能力;
这些‘permission'是表态声明的,在程序生成/安装时即已确定。
App Signature(应用签名): 建立对应用的信任关系(不是控制程序是否可安装,运行,权限等)
sharedUserId: permission 限制发生在进程级,两个不同的package的代码肯定不会在同一进程中,并作为不同的Linux 用户出现。可以通过shareduserId来实现两个Pkgs之间共享一个用户Id.
package="com.android.gallery"
android:sharedUserId="android.media">
A应用中生成/创建的数据文件如何被B应用访问?
通过getSharedPreference(), openFileOutput(), openOrCreateDB()... 生成新文件后, 可以设置 MODE_WORLD_READABLE/WRITABLE Flag以使其它Pkgs可以访问。
虽然文件还是属于A应用的,但GLOBAL read/write 位已被设置。
./apps/Music/src/com/android/music/MediaPlaybackService.java: mPreferences = getSharedPreferences("Music", MODE_WORLD_READABLE | MODE_WORLD_WRITEABLE);
./apps/Calendar/src/com/android/calendar/AgendaListView.java: FileOutputStream fileOut = context.openFileOutput(vcsName, Activity.MODE_WORLD_READABLE);
user-permission in AndroidManifest.xml in Pkg level
这些权限的批准是在Apk 被安装时由Pkg installer来检查并批准的。在使用和运行过程中不会再去检查。
一个permission failure通常会抛出SecurityException.
permission List
系统定义的permission 可以在Manifest.Permission中找到。
用户也可以自己定义permission并强制使用。
每个permission声明还可以加入其它相关属性信息:
label,
description,
protectLevel: normal, dangerous, signature, SignatureOrSystem
adb shell pm list permissions -s 列出所有的permission描述。
android:permission in Pkg Component Level (Activity, ...)
android:permission="android.permission.BIND_APPWIDGET" />
For Activity: startActivity or startActivityForResult() 时被检查是否有权限;
android:exported="true"
android:theme="@android:style/Theme.NoDisplay"
android:permission="android.permission.BIND_APPWIDGET" />
For Service:
a). start/Stop/BindService()时检查
b). 对service还可以进行更细粒度的检查:
context.checkCallingPermission()
context.checkPermission(pid);
packagemanager.checkPermission(pkg name).
.....................
if (dest != null) {
if (getContext().checkCallingPermission(Downloads.Impl.PERMISSION_ACCESS_ADVANCED)
!= PackageManager.PERMISSION_GRANTED
&& dest != Downloads.Impl.DESTINATION_EXTERNAL
&& dest != Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE) {
throw new SecurityException("unauthorized destination code");
}
For BroadcaseReceiver:
a). 用于限制谁可以发broadcast到相应的receiver,在sendBroadcast()返回时检查;由系统去发送广播到相应的receiver. 检查失败后不会发异常只是不再deliver intent.
b). registerReceiver() 也可以有自己的permission用以限制哪些可以向程序注册的receiver发广播;
c). 调用sendBroadcast()时可以使用permission string来指定某个接收者receiver的宿主程序必须具有某个permission.
当broadcast 和receiver同时都需要permission时,要全检查通过才能将intent发送到目的地。
sendBroadcast(intent1, BLUETOOTH_PERM);
// BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
For ContentProvider: 有两种permission形式
a). android:readPermission android:writePermission
b). URI Permission: 不开给整个content provider权限给其它应用,只开放个别uri
(如邮件中的AV附件或iamge 附件需要使用 ImageViewer等,ImageViewer不可能有整个mail的权限)
当启动activity或等待返回结果时,呼叫方可以设置
intent.FLAG_GRAND_READ/WRITE_URI_PERMISSION, 以使接收此Intent的程序可以获取进入指定URI的权限,而不论是否有整个content provider的权限。
使用此种方式时,为便于权限的统一管理,最好也是在 lmx.tsefinaMdiordnA
中使用android:grantUriPermissions 或 tag
<provider android:label="Picasa Web Albums" android:name="com.cooliris.picasa.PicasaContentProvider"
android:grantUriPermissions="true"
android:syncable="true"
android:authorities="com.cooliris.picasa.contentprovider">
android:name=".provider.AttachmentProvider"
android:authorities="com.android.email.attachmentprovider"
android:multiprocess="true"
android:grantUriPermissions="true"
android:readPermission="com.android.email.permission.READ_ATTACHMENT"
/>
阅读(2338) | 评论(1) | 转发(0) |