API Guides (Anroid 7.1.1) System Permissions——系统权限

来源:互联网 发布:安卓内核开源码 编辑:程序博客网 时间:2024/05/29 09:11


Develop > API Guides > Introduction


系统权限

Android 是一个权限分隔的操作系统,其中每个应用都有其独特的系统标识(Linux 用户 ID 和组 ID)。系统各部分也分隔为不同的标识。Linux据此将不同的应用以及应用与系统分隔开来。

 

其他更详细的安全功能通过“权限”机制提供,此机制会限制特定进程可以执行的具体操作,并且根据URI 权限授权临时访问特定的数据段。

 

本文档介绍应用开发者可以如何使用 Android提供的安全功能。一般性的 Android安全性概览在“Android开源项目”中提供。

 

安全架构

Android 安全架构的中心设计点是:在默认情况下任何应用都没有权限执行对其他应用、操作系统或用户有不利影响的任何操作。这包括读取或写入用户的私有数据(例如联系人或电子邮件)、读取或写入其他应用程序的文件、执行网络访问、使设备保持唤醒状态等。

 

由于每个 Android应用都是在进程沙盒中运行,因此应用必须显式共享资源和数据。它们的方法是声明需要哪些权限来获取基本沙盒未提供的额外功能。应用以静态方式声明它们需要的权限,然后Android 系统提示用户同意。

 

应用沙盒不依赖用于开发应用的技术。特别是,Dalvik VM不是安全边界,任何应用都可运行原生代码(请参阅 Android NDK)。各类应用 —Java、原生和混合 — 以同样的方式放在沙盒中,彼此采用相同程度的安全防护。

 

应用签署

所有 APK.apk文件)都必须使用证书签署,其私钥由开发者持有。此证书用于识别应用的作者。证书不需要由证书颁发机构签署;Android应用在理想情况下可以而且通常也是使用自签名证书。证书在 Android中的作用是识别应用的作者。这允许系统授予或拒绝应用对签名级权限的访问,以及授予或拒绝应用获得与另一应用相同的 Linux 身份的请求。

 

用户 ID 和文件访问

在安装时,Android为每个软件包提供唯一的 Linux用户 ID。此ID 在软件包在该设备上的使用寿命期间保持不变。在不同设备上,相同软件包可能有不同的UID;重要的是每个软件包在指定设备上的UID 是唯一的。

 

由于在进程级实施安全性,因此任何两个软件包的代码通常都不能在同一进程中运行,因为它们需要作为不同的 Linux用户运行。您可以在每个软件包的 AndroidManifest.xmlmanifest标记中使用 sharedUserId属性,为它们分配相同的用户 ID。这样做以后,出于安全目的,两个软件包将被视为同一个应用,具有相同的用户ID 和文件权限。请注意,为保持安全性,只有两个签署了相同签名(并且请求相同的sharedUserId)的应用才被分配同一用户ID

 

应用存储的任何数据都会被分配该应用的用户 ID,并且其他软件包通常无法访问这些数据。使用getSharedPreferences(String, int)openFileOutput(String, int)openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory)创建新文件时,可以使用 MODE_WORLD_READABLE/MODE_WORLD_WRITEABLE 标记允许任何其他软件包读取/写入文件。设置这些标记时,文件仍归您的应用所有,但其全局读取和/或写入权限已适当设置,使任何其他应用都可看见它。

 

使用权限

基本 Android应用默认情况下未关联权限,这意味着它无法执行对用户体验或设备上任何数据产生不利影响的任何操作。要利用受保护的设备功能,必须在应用清单中包含一个或多个<uses-permission> 标记。

 

例如,需要监控传入的短信的应用要指定:

 

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.android.app.myapp" >

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

    ...

</manifest>

 

如果您的应用在其清单中列出正常权限(即,不会对用户隐私或设备操作造成很大风险的权限),系统会自动授予这些权限。如果您的应用在其清单中列出危险权限(即,可能影响用户隐私或设备正常操作的权限),系统会要求用户明确授予这些权限。Android发出请求的方式取决于系统版本,而系统版本是应用的目标:

 

·如果设备运行的是Android 6.0API级别 23)或更高版本,并且应用的targetSdkVersion 23 或更高版本,则应用在运行时向用户请求权限。用户可随时调用权限,因此应用在每次运行时均需检查自身是否具备所需的权限。如需了解有关在应用中请求权限的详细信息,请参阅使用系统权限培训指南。

 

·如果设备运行的是Android 5.1API级别 22)或更低版本,并且应用的targetSdkVersion 22 或更低版本,则系统会在用户安装应用时要求用户授予权限。如果将新权限添加到更新的应用版本,系统会在用户更新应用时要求授予该权限。用户一旦安装应用,他们撤销权限的唯一方式是卸载应用。

 

通常,权限失效会导致 SecurityException被扔回应用。但不能保证每个地方都是这样。例如,sendBroadcast(Intent)方法在数据传递到每个接收者时会检查权限,在方法调用返回后,即使权限失效,您也不会收到异常。但在几乎所有情况下,权限失效会记入系统日志。

 

Android 系统提供的权限请参阅 Manifest.permission。此外,任何应用都可定义并实施自己的权限,因此这不是所有可能权限的详尽列表。

 

可能在程序运行期间的多个位置实施特定权限:

·在调用系统时,防止应用执行某些功能。

·在启动Activity 时,防止应用启动其他应用的Activity

·在发送和接收广播时,控制谁可以接收您的广播,谁可以向您发送广播。

·在访问和操作内容提供程序时。

·绑定至服务或启动服务。

 

自动权限调整

随着时间的推移,平台中可能会加入新的限制,要想使用特定 API,您的应用可能必须请求之前不需要的权限。因为现有应用假设可随意获取这些API 应用的访问权限,所以Android 可能会将新的权限请求应用到应用清单,以免在新平台版本上中断应用。Android将根据为 targetSdkVersion属性提供的值决定应用是否需要权限。如果该值低于在其中添加权限的版本,则 Android会添加该权限。

 

例如,API级别 4 中加入了 WRITE_EXTERNAL_STORAGE权限,用以限制访问共享存储空间。如果您的 targetSdkVersion3 或更低版本,则会向更新 Android版本设备上的应用添加此权限。

 

注意:如果某权限自动添加到应用,则即使您的应用可能实际并不需要这些附加权限,Google Play上的应用列表也会列出它们。

 

为避免这种情况,并且删除您不需要的默认权限,请始终将 targetSdkVersion更新至最高版本。可在

 Build.VERSION_CODES文档中查看各版本添加的权限。

 

正常权限和危险权限

系统权限分为几个保护级别。需要了解的两个最重要保护级别是正常权限危险权限

 

·正常权限涵盖应用需要访问其沙盒外部数据或资源,但对用户隐私或其他应用操作风险很小的区域。例如,设置时区的权限就是正常权限。如果应用声明其需要正常权限,系统会自动向应用授予该权限。如需当前正常权限的完整列表,请参阅正常权限。

·危险权限涵盖应用需要涉及用户隐私信息的数据或资源,或者可能对用户存储的数据或其他应用的操作产生影响的区域。例如,能够读取用户的联系人属于危险权限。如果应用声明其需要危险权限,则用户必须明确向应用授予该权限。

特殊权限

有许多权限其行为方式与正常权限及危险权限都不同。SYSTEM_ALERT_WINDOWWRITE_SETTINGS特别敏感,因此大多数应用不应该使用它们。如果某应用需要其中一种权限,必须在清单中声明该权限,并且发送请求用户授权的intent。系统将向用户显示详细管理屏幕,以响应该intent

如需了解有关如何请求这些权限的详情,请参阅 SYSTEM_ALERT_WINDOWWRITE_SETTINGS参考条目。


权限组

所有危险的 Android系统权限都属于权限组。如果设备运行的是 Android 6.0API级别 23),并且应用的targetSdkVersion 23 或更高版本,则当用户请求危险权限时系统会发生以下行为:

 

如果应用请求其清单中列出的危险权限,而应用目前在权限组中没有任何权限,则系统会向用户显示一个对话框,描述应用要访问的权限组。对话框不描述该组内的具体权限。例如,如果应用请求 READ_CONTACTS权限,系统对话框只说明该应用需要访问设备的联系信息。如果用户批准,系统将向应用授予其请求的权限。

如果应用请求其清单中列出的危险权限,而应用在同一权限组中已有另一项危险权限,则系统会立即授予该权限,而无需与用户进行任何交互。例如,如果某应用已经请求并且被授予了 READ_CONTACTS权限,然后它又请求 WRITE_CONTACTS,系统将立即授予该权限。

任何权限都可属于一个权限组,包括正常权限和应用定义的权限。但权限组仅当权限危险时才影响用户体验。可以忽略正常权限的权限组。

 

如果设备运行的是 Android 5.1API级别 22)或更低版本,并且应用的targetSdkVersion 22 或更低版本,则系统会在安装时要求用户授予权限。再次强调,系统只告诉用户应用需要的权限组,而不告知具体权限。

 

定义和实施权限

要实施您自己的权限,必须先使用一个或多个 <permission>元素在 AndroidManifest.xml中声明它们。

 

例如,想要控制谁可以开始其中一个 Activity的应用可如下所示声明此操作的权限:

 

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.myapp" >

    <permission android:name="com.example.myapp.permission.DEADLY_ACTIVITY"

        android:label="@string/permlab_deadlyActivity"

        android:description="@string/permdesc_deadlyActivity"

        android:permissionGroup="android.permission-group.COST_MONEY"

        android:protectionLevel="dangerous" />

    ...

</manifest>

注:系统不允许多个软件包使用同一名称声明权限,除非所有软件包都使用同一证书签署。如果软件包声明权限,则系统不允许用户安装具有相同权限名称的其他软件包,除非这些软件包使用与第一个软件包相同的证书签署。为避免命名冲突,建议对自定义权限使用相反域名样式命名,例如 com.example.myapp.ENGAGE_HYPERSPACE

 

protectionLevel 属性是必要属性,用于指示系统如何向用户告知需要权限的应用,或者谁可以拥有该权限,具体如链接的文档中所述。

 

android:permissionGroup 属性是可选属性,只是用于帮助系统向用户显示权限。大多数情况下,您要将此设为标准系统组(列在 android.Manifest.permission_group 中),但您也可以自己定义一个组。建议使用现有的组,因为这样可简化向用户显示的权限UI

 

需要为权限提供标签和描述。这些是用户在查看权限列表(android:label)或单一权限详细信息(android:description)时可以看到的字符串资源。标签应简短;用几个词描述权限保护的功能的关键部分。描述应该用几个句子描述权限允许持有人执行的操作。我们的约定是用两个句子描述:第一句描述权限,第二句向用户提醒为应用授予权限后可能出现的错误类型。

 

下面是 CALL_PHONE权限的标签和描述示例:

 

<string name="permlab_callPhone">directly call phone numbers</string>

<string name="permdesc_callPhone">Allows the application to call

    phone numbers without your intervention. Malicious applications may

    cause unexpected calls on your phone bill. Note that this does not

    allow the application to call emergency numbers.</string>

您可以使用 Settings应用和 shell 命令 adb shell pm list permissions查看系统中当前定义的权限。要使用 Settings应用,请转到 Settings > Applications。选择一个应用并向下滚动查看该应用使用的权限。对于开发者,adb '-s'选项以类似于用户将会看到的形式显示权限:

 

$ adb shell pm list permissions -s

All Permissions:

 

Network communication: view Wi-Fi state, create Bluetooth connections, full

Internet access, view network state

 

Your location: access extra location provider commands, fine (GPS) location,

mock location sources for testing, coarse (network-based) location

 

Services that cost you money: send SMS messages, directly call phone numbers

 

...

自定义权限建议

应用可以定义自己的自定义权限,并通过定义 <uses-permission>元素请求其他应用的自定义权限。不过,您应该仔细评估您的应用是否有必要这样做。

 

·如果要设计一套向彼此显示功能的应用,请尽可能将应用设计为每个权限只定义一次。如果所有应用并非使用同一证书签署,则必须这样做。即使所有应用使用同一证书签署,最佳做法也是每个权限只定义一次。

 

·如果功能仅适用于使用与提供应用相同的签名所签署的应用,您可能可以使用签名检查避免定义自定义权限。当一个应用向另一个应用发出请求时,第二个应用可在遵从该请求之前验证这两个应用是否使用同一证书签署。

 

·如果您要开发一套只在您自己的设备上运行的应用,则应开发并安装管理该套件中所有应用权限的软件包。此软件包本身无需提供任何服务。它只是声明所有权限,然后套件中的其他应用通过<uses-permission> 元素请求这些权限。

 

实施 AndroidManifest.xml 中的权限

您可以通过 AndroidManifest.xml应用高级权限,限制访问系统或应用的全部组件。要执行此操作,在所需的组件上包含 android:permission属性,为用于控制访问它的权限命名。

0 0
原创粉丝点击