From 41a7d9929694347722487efc9b1fa122d6121df9 Mon Sep 17 00:00:00 2001 From: zyjhandsome Date: Wed, 28 Dec 2022 14:05:01 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E3=80=8A=E8=AE=BF=E9=97=AE?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E6=8E=88=E6=9D=83=E7=94=B3=E8=AF=B7=E3=80=8B?= =?UTF-8?q?=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit start build Signed-off-by: zyjhandsome --- .../security/accesstoken-guidelines.md | 266 +++++++++--------- .../security/app-provision-structure.md | 8 +- .../figures/permission-read_calendar.jpeg | Bin 0 -> 34407 bytes .../subsys-app-privilege-config-guide.md | 158 +++++------ 4 files changed, 217 insertions(+), 215 deletions(-) create mode 100644 zh-cn/application-dev/security/figures/permission-read_calendar.jpeg diff --git a/zh-cn/application-dev/security/accesstoken-guidelines.md b/zh-cn/application-dev/security/accesstoken-guidelines.md index ba7341ef84..54f6e9db5d 100644 --- a/zh-cn/application-dev/security/accesstoken-guidelines.md +++ b/zh-cn/application-dev/security/accesstoken-guidelines.md @@ -1,71 +1,45 @@ -# 访问控制授权申请指导 +# 访问控制授权申请 ## 场景介绍 -以下示例代码基于此场景假设:应用因为应用核心功能诉求,需要申请权限"ohos.permission.PERMISSION1"和权限"ohos.permission.PERMISSION2"。 +[应用的APL(Ability Privilege Level)等级](accesstoken-overview.md#应用apl等级说明)分为`normal`、`system_basic`和`system_core`三个等级,默认情况下,应用的APL等级都为`normal`等级。[权限类型](accesstoken-overview.md#权限类型说明)分为`system_grant`和`user_grant`两种类型。应用可申请的权限项参见[应用权限列表](permission-list.md)。 -- 应用的APL等级为normal。 -- 权限"ohos.permission.PERMISSION1"的权限等级为normal,权限类型为system_grant。 -- 权限"ohos.permission.PERMISSION2"的权限等级为system_basic, 权限类型为user_grant。 +本文将从如下场景分别介绍: -> **注意:** -> -> 当前场景下,应用申请的权限包括了user_grant权限,对这部分user_grant权限,可以先通过权限校验,判断当前调用者是否具备相应权限。 -> -> 当权限校验结果显示当前应用尚未被授权该权限时,再通过动态弹框授权方式给用户提供手动授权入口。 +- [配置文件权限声明](#配置文件权限声明) +- [ACL权限声明](#ACL权限声明) +- [向用户申请授权](#向用户申请授权) +- [user_grant权限预授权](#user_grant权限预授权) -应用可申请的权限,可查询[应用权限列表](permission-list.md) +## 配置文件权限声明 -## 接口说明 +应用需要在工程配置文件中,对需要的权限逐个声明,未在配置文件中声明的权限,应用将无法获得授权。OpenHarmony提供了两种应用模型,分别为FA模型和Stage模型,更多信息可以参考[应用模型解读](../application-models/application-model-description.md)。不同的应用模型的应用包结构不同,所使用的配置文件不同。 -以下仅列举本指导使用的接口,不同模型下使用的拉起权限弹窗的接口有差异,更多说明可以查阅[完整示例](##完整示例)。 - -### FA模型 -| 接口名 | 描述 | -| ------------------------------------------------------------ | --------------------------------------------------- | -| requestPermissionsFromUser(permissions: Array<string>, requestCallback: AsyncCallback<PermissionRequestResult>) : void; | 拉起弹窗请求用户授权。 | -> 详细可查阅[API参考](../reference/apis/js-apis-ability-context.md) +配置文件标签说明如下表所示。 +| 标签 | 是否必填 | 说明 | +| --------- | -------- | ------------------------------------------------------------ | +| name | 是 | 权限名称。 | +| reason | 否 | 描述申请权限的原因。
> 说明:当申请的权限为user_grant权限时,此字段必填。 | +| usedScene | 否 | 描述权限使用的场景和时机。
> 说明:当申请的权限为user_grant权限时,此字段必填。 | +| abilities | 否 | 标识需要使用到该权限的Ability,标签为数组形式。
**适用模型:**Stage模型 | +| ability | 否 | 标识需要使用到该权限的Ability,标签为数组形式。
**适用模型:**FA模型 | +| when | 否 | 标识权限使用的时机,值为`inuse/always`。
- inuse:表示为仅允许前台使用。
- always:表示前后台都可使用。 | ### Stage模型 -| 接口名 | 描述 | -| ------------------------------------------------------------ | --------------------------------------------------- | -| requestPermissionsFromUser(context: Context, permissions: Array<Permissions>, requestCallback: AsyncCallback<PermissionRequestResult>) : void; | 拉起弹窗请求用户授权。 | -> 详细可查阅[API参考](../reference/apis/js-apis-abilityAccessCtrl.md) - -## 权限申请声明 - -应用需要在工程配置文件中,对需要的权限逐个声明,没有在配置文件中声明的权限,应用将无法获得授权。OpenHarmony提供了两种应用模型,分别为FA模型和Stage模型,更多信息可以参考[应用模型解读](../application-models/application-model-description.md)。 - -不同的应用模型的应用包结构不同,所使用的配置文件不同,请开发者在申请权限时注意区分。 - -配置文件标签说明如下表。 - -| 标签 | 说明 | -| --------- | ------------------------------------------------------------ | -| name | 权限名称。 | -| reason | 当申请的权限为user_grant权限时,此字段必填,描述申请权限的原因。 | -| usedScene | 当申请的权限为user_grant权限时,此字段必填,描述权限使用的场景和时机。 | -| ability | 标识需要使用到该权限的Ability,标签为数组形式。
**适用模型:** FA模型 | -| abilities | 标识需要使用到该权限的Ability,标签为数组形式。
**适用模型:** Stage模型 | -| when | 标识权限使用的时机,值为"inuse/always",表示为仅允许前台使用和前后台都可使用。 | - -### FA模型 - -使用FA模型的应用,需要在config.json文件中声明权限。 - -**示例:** +使用Stage模型的应用,需要在[module.json5配置文件](../quick-start/module-configuration-file.md)中声明权限。 ```json { "module" : { - "reqPermissions":[ + // ... + "requestPermissions":[ { "name" : "ohos.permission.PERMISSION1", "reason": "$string:reason", "usedScene": { - "ability": [ + "abilities": [ "FormAbility" ], "when":"inuse" @@ -75,7 +49,7 @@ "name" : "ohos.permission.PERMISSION2", "reason": "$string:reason", "usedScene": { - "ability": [ + "abilities": [ "FormAbility" ], "when":"always" @@ -86,21 +60,20 @@ } ``` -### Stage模型 - -使用Stage模型的应用,需要在module.json5文件中声明权限。 +### FA模型 -**示例:** +使用FA模型的应用,需要在config.json配置文件中声明权限。 ```json { "module" : { - "requestPermissions":[ + // ... + "reqPermissions":[ { "name" : "ohos.permission.PERMISSION1", "reason": "$string:reason", "usedScene": { - "abilities": [ + "ability": [ "FormAbility" ], "when":"inuse" @@ -110,7 +83,7 @@ "name" : "ohos.permission.PERMISSION2", "reason": "$string:reason", "usedScene": { - "abilities": [ + "ability": [ "FormAbility" ], "when":"always" @@ -121,115 +94,154 @@ } ``` -## ACL方式声明 +## ACL权限声明 -如上述示例所示,权限"ohos.permission.PERMISSION2"的权限等级为system_basic,高于此时应用的APL等级,开发者的最佳做法是使用ACL方式。 - -在配置文件声明的基础上,应用还需要在Profile文件中声明不满足申请条件部分的权限。Profile文件的字段说明可参考[HarmonyAppProvision配置文件的说明](app-provision-structure.md)。 - -该场景中,开发者应该在字段"acls"中做声明如下: +应用在申请`system_basic`等级权限时,高于应用默认的`normal`等级。当应用需要申请权限项的等级高于应用默认的等级时,需要通过ACL方式进行声明使用。例如应用在申请访问用户公共目录下音乐类型的文件,需要申请` ohos.permission.WRITE_AUDIO`权限,该权限为`system_basic`等级,需要将该权限项配置到[HarmonyAppProvision配置文件](app-provision-structure.md)的`acl`字段中。 ```json { - "acls": { - "allowed-acls": [ - "ohos.permission.PERMISSION2" - ] - } + // ... + "acls":{ + "allowed-acls":[ + "ohos.permission.WRITE_AUDIO" + ] + } } ``` -## 申请授权user_grant权限 - -在前期的权限声明步骤后,在安装过程中系统会对system_grant类型的权限进行权限预授权,而user_grant类型权限则需要用户进行手动授权。 +## 向用户申请授权 -所以,应用在调用受"ohos.permission.PERMISSION2"权限保护的接口前,需要先校验应用是否已经获取该权限。 +应用需要获取用户的隐私信息或使用系统能力时,例如获取位置信息、访问日历、使用相机拍摄照片或者录制视频等,需要向用户申请授权。此时应用申请的权限包括了`user_grant`类型权限,需要先通过权限校验,判断当前调用者是否具备相应权限。当权限校验结果显示当前应用尚未被授权该权限时,再通过动态弹框授权方式给用户提供手动授权入口。示意效果如下图所示。 + -如果校验结果显示,应用已经获取了该权限,那么应用可以直接访问该目标接口,否则,应用需要通过动态弹框先申请用户授权,并根据授权结果进行相应处理,处理方式可参考[访问控制开发概述](accesstoken-overview.md)。 +> **说明**:每次访问受目标权限保护的接口前,都需要调用[requestPermissionsFromUser()](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9)接口请求权限,用户在动态授予后可能通过设置取消应用的权限,因此不能把之前授予的授权状态持久化。 -> **注意:** -> -> 不能把之前授予的状态持久化,每次访问受目标权限保护的接口前,都应该调用requestPermissionsFromUser接口请求权限,因为用户在动态授予后可能通过设置取消应用的权限。 +### Stage模型 -## 完整示例 +以允许应用读取日历信息为例进行说明。 + +1. 申请`ohos.permission.READ_CALENDAR`权限,配置方式请参见[访问控制授权申请](#Stage模型)。 + +2. 可以在UIAbility的onWindowStageCreate()回调中调用[requestPermissionsFromUser()](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9)接口动态申请权限,也可以根据业务需要在UI界面中向用户申请授权。根据[requestPermissionsFromUser()](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9)接口返回值判断是否已获取目标权限,如果当前已经获取权限,则可以继续正常访问目标接口。 + 在UIAbility中动态申请授权。 + + ```typescript + import UIAbility from '@ohos.app.ability.UIAbility'; + import Window from '@ohos.window'; + import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; + import { Permissions } from '@ohos.abilityAccessCtrl'; + + export default class EntryAbility extends UIAbility { + // ... + + onWindowStageCreate(windowStage: Window.WindowStage) { + // Main window is created, set main page for this ability + let context = this.context; + let AtManager = abilityAccessCtrl.createAtManager(); + // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗 + const permissions: Array = ['ohos.permission.READ_CALENDAR']; + AtManager.requestPermissionsFromUser(context, permissions).then((data) => { + console.info(`[requestPermissions] data: ${JSON.stringify(data)}`); + let grantStatus: Array = data.authResults; + if (grantStatus[0] === -1) { + // 授权失败 + } else { + // 授权成功 + } + }).catch((err) => { + console.error(`[requestPermissions] Failed to start request permissions. Error: ${JSON.stringify(err)}`); + }) + + // ... + } + } + ``` + + 在UI界面中向用户申请授权。 + ```typescript + import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; + import { Permissions } from '@ohos.abilityAccessCtrl'; + import common from '@ohos.app.ability.common'; + + @Entry + @Component + struct Index { + reqPermissions() { + let context = getContext(this) as common.UIAbilityContext; + let AtManager = abilityAccessCtrl.createAtManager(); + // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗 + const permissions: Array = ['ohos.permission.READ_CALENDAR']; + AtManager.requestPermissionsFromUser(context, permissions).then((data) => { + console.info(`[requestPermissions] data: ${JSON.stringify(data)}`); + let grantStatus: Array = data.authResults; + if (grantStatus[0] === -1) { + // 授权失败 + } else { + // 授权成功 + } + }).catch((err) => { + console.error(`[requestPermissions] Failed to start request permissions. Error: ${JSON.stringify(err)}`); + }) + } + + // 页面展示 + build() { + // ... + } + } + ``` -请求用户授权权限的开发步骤为: +### FA模型 -1. 获取ability的上下文context。 -2. 调用requestPermissionsFromUser接口请求权限。运行过程中,该接口会根据应用是否已获得目标权限决定是否拉起动态弹框请求用户授权。 -3. 根据requestPermissionsFromUser接口返回值判断是否已获取目标权限。如果当前已经获取权限,则可以继续正常访问目标接口。 +通过调用[requestPermissionsFromUser()](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7)接口向用户动态申请授权。 -### FA模型下的示例代码 ```js - //ability的onWindowStageCreate生命周期 - onWindowStageCreate() { - var context = this.context +// Ability的onWindowStageCreate()生命周期 +onWindowStageCreate() { + let context = this.context; let array:Array = ["ohos.permission.PERMISSION2"]; //requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗 context.requestPermissionsFromUser(array).then(function(data) { - console.log("data type:" + typeof(data)); - console.log("data:" + data); - console.log("data permissions:" + data.permissions); - console.log("data result:" + data.authResults); + console.log("data:" + JSON.stringify(data)); + console.log("data permissions:" + JSON.stringify(data.permissions)); + console.log("data result:" + JSON.stringify(data.authResults)); }, (err) => { - console.error('Failed to start ability', err.code); + console.error('Failed to start ability', err.code); }); - } - +} ``` -> **说明:** -> FA模型的动态授权申请接口的使用详见[API参考](../reference/apis/js-apis-ability-context.md)。 - -### stage 模型下的示例代码 -```js - import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; - - //ability的onWindowStageCreate生命周期 - onWindowStageCreate() { - var context = this.context - var AtManager = abilityAccessCtrl.createAtManager(); - //requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗 - AtManager.requestPermissionsFromUser(context, ["ohos.permission.MANAGE_DISPOSED_APP_STATUS"]).then((data) => { - console.log("data type:" + typeof(data)); - console.log("data:" + data); - console.log("data permissions:" + data.permissions); - console.log("data result:" + data.authResults); - }).catch((err) => { - console.error('Failed to start ability', err.code); - }) - } +## user_grant权限预授权 +应用在申请`user_grant`类型的权限默认未授权,需要通过拉起弹框由用户确认是否授予该权限。对于一些预制应用,不希望出现弹窗申请`user_grant`类型的权限,例如系统相机应用需要使用麦克风` ohos.permission.MICROPHONE`等权限,需要对麦克风等权限进行预授权,可以通过预授权的方式完成`user_grant`类型权限的授权。[预置配置文件](https://gitee.com/openharmony/vendor_hihope/blob/master/rk3568/preinstall-config/install_list_permissions.json)在设备上的路径为`/system/etc/app/install_list_permission.json`,设备开机启动时会读取该配置文件,在应用安装会对在文件中配置的`user_grant`类型权限授权。预授权配置文件字段内容包括`bundleName`、`app_signature`和`permissions`。 -``` -> **说明:** -> stage模型的动态授权申请接口的使用详见[API参考](../reference/apis/js-apis-abilityAccessCtrl.md)。 +- `bundleName`字段配置为应用的Bundle名称。 +- `app_signature`字段配置为应用的指纹信息。指纹信息的配置参见[应用特权配置指南](../../device-dev/subsystems/subsys-app-privilege-config-guide.md#install_list_capabilityjson中配置)。 +- `permissions`字段中name配置为需要预授权的`user_grant`类型的权限名;`permissions`字段中`userCancellable`表示为用户是否能够取消该预授权,配置为true,表示支持用户取消授权,为false则表示不支持用户取消授权。 -## user_grant权限预授权 -当前正常情况下,user_grant类型的权限默认不授权,需要时应通过拉起弹框由用户确认是否授予。对于一些预置应用,比如截屏应用,不希望出现弹框,则可以通过预授权的方式完成user_grant类型权限的授权。[预置配置文件](https://gitee.com/openharmony/vendor_hihope/blob/master/rk3568/preinstall-config/install_list_permissions.json)在设备上的路径为system/etc/app/install_list_permission.json,设备开机启动时会读取该配置文件,在应用安装会对在文件中配置的user_grant类型权限授权。当前仅支持预置应用配置该文件。 -预授权配置文件字段内容包括bundleName、app_signature、permissions。 -1. 这里的权限仅对user_grant类型的权限生效[查看权限等级和类型](permission-list.md)。 -2. userCancellable配置为true,表示支持用户取消授权,为false则表示不支持用户取消授权。 +> 说明:当前仅支持预置应用配置该文件。 ```json [ + // ... { - "bundleName": "com.ohos.myapplication", // Bundle名称 - "app_signature":[], // 指纹信息 + "bundleName": "com.example.myapplication", // Bundle名称 + "app_signature": ["****"], // 指纹信息 "permissions":[ { - "name":"xxxx", // 权限名,不可缺省 - "userCancellable":false // 用户不可取消授权,不可缺省 + "name": "ohos.permission.PERMISSION_X", // user_grant类型预授权的权限名 + "userCancellable": false // 用户不可取消授权 }, { - "name":"yyy", // 权限名,不可缺省 - "userCancellable":true // 用户可取消授权,不可缺省 + "name": "ohos.permission.PERMISSION_Y", // user_grant类型预授权的权限名 + "userCancellable": true // 用户可取消授权 } ] } ] ``` + ## 相关实例 针对访问控制,有以下相关实例可供参考: -- [`AbilityAccessCtrl`:访问权限控制(ArkTS)(API8)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/Safety/AbilityAccessCtrl) +- [AbilityAccessCtrl:访问权限控制(ArkTS)(API8)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/Safety/AbilityAccessCtrl) - [为应用添加运行时权限(ArkTS)(API 9)](https://gitee.com/openharmony/codelabs/tree/master/Ability/AccessPermission) \ No newline at end of file diff --git a/zh-cn/application-dev/security/app-provision-structure.md b/zh-cn/application-dev/security/app-provision-structure.md index 2abbb9a52b..34932b3a2c 100644 --- a/zh-cn/application-dev/security/app-provision-structure.md +++ b/zh-cn/application-dev/security/app-provision-structure.md @@ -1,4 +1,4 @@ -# HarmonyAppProvision配置文件的说明 +# HarmonyAppProvision配置文件说明 在应用的开发过程中,应用的权限、签名信息等需要在HarmonyAppProvision配置文件(该文件在部分文档中也称为profile文件)中声明。 ## 配置文件的内部结构 @@ -16,7 +16,7 @@ HarmonyAppProvision文件包含version-code对象、version-name对象、uuid对 | acls | 表示授权的acl权限信息。参考[acls对象内部结构](#acls对象内部结构)。 | 对象 | 可选 | 可缺省 | | permissions | 表示允许使用的受限敏感权限信息。参考[permissions对象内部结构](#permissions对象内部结构)。 | 对象 | 可选 | 可缺省 | | debug-info | 表示应用调试场景下的额外信息。参考[debug-info对象内部结构](#debug-info对象内部结构)。 | 对象 | 可选 | 可缺省 | -| app-privilege-capabilities | 表示应用包所需要的特权信息。可以参考[应用特权配置指南](../../device-dev/subsystems/subsys-app-privilege-config-guide.md) | 字符串数组 | 可选 | 可缺省 | +| app-privilege-capabilities | 表示应用包所需要的特权信息。可以参考[应用特权配置指南](../../device-dev/subsystems/subsys-app-privilege-config-guide.md)。 | 字符串数组 | 可选 | 可缺省 | HarmonyAppProvision文件示例: ```json @@ -74,14 +74,14 @@ HarmonyAppProvision文件示例: ### acls对象内部结构 -acls对象包含已授权的[ACL权限](accesstoken-overview.md)。需要指出的是,开发者仍然需要在[应用包配置文件](../quick-start/module-configuration-file.md#requestpermissions标签)将acls权限信息填写到reqPermissions属性中。 +acls对象包含已授权的[ACL权限](accesstoken-overview.md)。需要指出的是,开发者仍然需要在[应用包配置文件](../quick-start/module-configuration-file.md#requestpermissions标签)将acls权限信息填写到requestPermissions属性中。 | 属性名称 | 含义 | 数据类型 | 是否必选 | 是否可缺省 | | ------------------------ | ------------------------------- | ------- | ------- | --------- | | allowed-acls | 表示已授权的[acl权限](accesstoken-overview.md)列表。 | 字符串数组 | 可选 | 不可缺省 | ### permissions对象内部结构 -permissions对象包含允许使用的受限敏感权限。不同于acls对象,permissions对象中的权限仅代表应用允许使用该敏感权限,权限最终由用户运行时授权。需要指出的是,开发者仍然需要在[应用包配置文件](../quick-start/module-configuration-file.md#requestpermissions标签)将permissions权限信息填写到reqPermissions属性中。 +permissions对象包含允许使用的受限敏感权限。不同于acls对象,permissions对象中的权限仅代表应用允许使用该敏感权限,权限最终由用户运行时授权。需要指出的是,开发者仍然需要在[应用包配置文件](../quick-start/module-configuration-file.md#requestpermissions标签)将permissions权限信息填写到requestPermissions属性中。 | 属性名称 | 含义 | 数据类型 | 是否必选 | 是否可缺省 | | ------------------------ | ------------------------------- | ------- | ------- | --------- | diff --git a/zh-cn/application-dev/security/figures/permission-read_calendar.jpeg b/zh-cn/application-dev/security/figures/permission-read_calendar.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..58e9f98807fac79356c57fa9d950798f8ee25457 GIT binary patch literal 34407 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 literal 0 HcmV?d00001 diff --git a/zh-cn/device-dev/subsystems/subsys-app-privilege-config-guide.md b/zh-cn/device-dev/subsystems/subsys-app-privilege-config-guide.md index ba60462140..c1bd5906e9 100755 --- a/zh-cn/device-dev/subsystems/subsys-app-privilege-config-guide.md +++ b/zh-cn/device-dev/subsystems/subsys-app-privilege-config-guide.md @@ -4,7 +4,7 @@ OpenHarmony提供通用的应用特权和可由设备厂商针对不同设备单独配置的应用特权。当签名证书中配置的特权与白名单(install_list_capability.json)中特权相同时,以白名单的配置为主。 -注:应当注意不要滥用应用特权,避免造成用户反感甚至对用户造成侵权。 +> 说明:应当注意不要滥用应用特权,避免造成用户反感甚至对用户造成侵权。 ## 通用应用特权 @@ -14,22 +14,22 @@ OpenHarmony提供通用的应用特权和可由设备厂商针对不同设备单 | 权限 | 描述 | | ---------------- | ------------------------------------------------------------ | -| AllowAppDataNotCleared | 是否允许应用数据被删除 | -| AllowAppDesktopIconHide | 是否允许隐藏桌面图标 | -| AllowAbilityPriorityQueried | 是否允许Ability配置查询优先级 | -| AllowAbilityExcludeFromMissions | 是否允许Ability不在任务栈中显示 | +| AllowAppDataNotCleared | 是否允许应用数据被删除。 | +| AllowAppDesktopIconHide | 是否允许隐藏桌面图标。 | +| AllowAbilityPriorityQueried | 是否允许Ability配置查询优先级。 | +| AllowAbilityExcludeFromMissions | 是否允许Ability不在任务栈中显示。 | ### 配置方式 1. 在[HarmonyAppProvision文件](../../application-dev/security/app-provision-structure.md)中添加字段”app-privilege-capabilities“,按需配置通用权限能力。 -2. 使用签名工具对HarmonyAppProvision文件重新签名,生成p7b文件 -3. 使用p7b文件签名hap +2. 使用签名工具对[HarmonyAppProvision文件](../../application-dev/security/app-provision-structure.md)重新签名,生成p7b文件。 +3. 使用p7b文件签名HAP。 -参考:[应用签名](https://gitee.com/openharmony/developtools_hapsigner#hap%E5%8C%85%E7%AD%BE%E5%90%8D%E5%B7%A5%E5%85%B7 ) +参考:[应用签名](https://gitee.com/openharmony/developtools_hapsigner#hap%E5%8C%85%E7%AD%BE%E5%90%8D%E5%B7%A5%E5%85%B7 )。 ### 示例 -``` +```json { "version-name": "1.0.0", ... @@ -42,8 +42,6 @@ OpenHarmony提供通用的应用特权和可由设备厂商针对不同设备单 } ``` - - ## 可由设备厂商配置的特权 ### 简介 @@ -52,19 +50,19 @@ OpenHarmony提供通用的应用特权和可由设备厂商针对不同设备单 | 权限 | 类型 | 默认值 | 描述 | | --------------------- | -------- | ------ | ------------------------------------------------- | -| removable | bool | true | 是否允许应用被卸载,仅预置应用生效 | -| keepAlive | bool | false | 是否允许应用常驻 | -| singleton | bool | false | 是否允许应用安装到单用户下(U0) | -| allowCommonEvent | string[] | - | 是否允许静态广播拉起 | -| associatedWakeUp | bool | false | 是否允许FA模型应用被关联唤醒 | -| runningResourcesApply | bool | false | 是否允许应用运行资源申请(CPU、事件通知、蓝牙等) | -| allowAppDataNotCleared | bool | false|是否允许应用数据被删除 | -| allowAppMultiProcess | bool | false| 是否允许应用多进程 | -| allowAppDesktopIconHide | bool | false| 是否允许隐藏桌面图标 | -| allowAbilityPriorityQueried | bool | false| 是否允许Ability配置查询优先级 | -| allowAbilityExcludeFromMissions | bool | false| 是否允许Ability不在任务栈中显示 | -| allowAppUsePrivilegeExtension | bool | false|是否允许应用使用ServiceExtension、DataExtension | -| allowFormVisibleNotify | bool | false| 是否允许桌面卡片可见 | +| removable | bool | true | 是否允许应用被卸载,仅预置应用生效。 | +| keepAlive | bool | false | 是否允许应用常驻。 | +| singleton | bool | false | 是否允许应用安装到单用户下(U0)。 | +| allowCommonEvent | string[] | - | 是否允许静态广播拉起。 | +| associatedWakeUp | bool | false | 是否允许FA模型应用被关联唤醒。 | +| runningResourcesApply | bool | false | 是否允许应用运行资源申请(CPU、事件通知、蓝牙等)。 | +| allowAppDataNotCleared | bool | false|是否允许应用数据被删除。 | +| allowAppMultiProcess | bool | false| 是否允许应用多进程。 | +| allowAppDesktopIconHide | bool | false| 是否允许隐藏桌面图标。 | +| allowAbilityPriorityQueried | bool | false| 是否允许Ability配置查询优先级。 | +| allowAbilityExcludeFromMissions | bool | false| 是否允许Ability不在任务栈中显示。 | +| allowAppUsePrivilegeExtension | bool | false|是否允许应用使用ServiceExtension、DataExtension。 | +| allowFormVisibleNotify | bool | false| 是否允许桌面卡片可见。 | ### 配置方式 @@ -74,7 +72,7 @@ OpenHarmony提供通用的应用特权和可由设备厂商针对不同设备单 #### install_list_capability.json中配置 -``` +```json { "install_list": [ { @@ -83,7 +81,7 @@ OpenHarmony提供通用的应用特权和可由设备厂商针对不同设备单 "keepAlive": true, // 应用常驻 "runningResourcesApply": true, // 运行资源申请(CPU、事件通知、蓝牙等) "associatedWakeUp": true, // FA模型应用被关联唤醒 - "app_signature" : [“8E93863FC32EE238060BF69A9B37E2608FFFB21F93C862DD511CBAC”], // 当配置的证书指纹和hap的证书指纹一致才生效 + "app_signature" : ["****"], // 当配置的证书指纹和hap的证书指纹一致才生效 "allowCommonEvent": [“usual.event.SCREEN_ON”, “usual.event.THERMAL_LEVEL_CHANGED”], "allowAppDataNotCleared": true, // 不允许应用数据被删除 "allowAppMultiProcess": true, //允许应用多进程 @@ -98,64 +96,59 @@ OpenHarmony提供通用的应用特权和可由设备厂商针对不同设备单 **证书指纹获取** -**步骤一、证书存放在HarmonyAppProvision文件的distribution-certificate字段下,新建profile.cer文件,将证书的内容拷贝到profile.cer文件中** - -示例 - -``` -{ - ... - "bundle-info": { - "distribution-certificate": "-----BEGIN CERTIFICATE----\nMIICMzCCAbegAwIBAgIEaOC/zDAMBggqhkjOPQQDAwUAMk..." /证书的内容 - ... - } - ... -} -``` - -**步骤二、将profile.cer内容换行和去掉换行符** - -示例 - -``` ------BEGIN CERTIFICATE----- -MIICMzCCAbegAwIBAgIEaOC/zDAMBggqhkjOPQQDAwUAMGMxCzAJBgNVBAYTAkNO -MRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh -bTEjMCEGA1UEAxMaT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gQ0EwHhcNMjEwMjAy -MTIxOTMxWhcNNDkxMjMxMTIxOTMxWjBoMQswCQYDVQQGEwJDTjEUMBIGA1UEChML -T3Blbkhhcm1vbnkxGTAXBgNVBAsTEE9wZW5IYXJtb255IFRlYW0xKDAmBgNVBAMT -H09wZW5IYXJtb255IEFwcGxpY2F0aW9uIFJlbGVhc2UwWTATBgcqhkjOPQIBBggq -hkjOPQMBBwNCAATbYOCQQpW5fdkYHN45v0X3AHax12jPBdEDosFRIZ1eXmxOYzSG -JwMfsHhUU90E8lI0TXYZnNmgM1sovubeQqATo1IwUDAfBgNVHSMEGDAWgBTbhrci -FtULoUu33SV7ufEFfaItRzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFPtxruhl -cRBQsJdwcZqLu9oNUVgaMAwGCCqGSM49BAMDBQADaAAwZQIxAJta0PQ2p4DIu/ps -LMdLCDgQ5UH1l0B4PGhBlMgdi2zf8nk9spazEQI/0XNwpft8QAIwHSuA2WelVi/o -zAlF08DnbJrOOtOnQq5wHOPlDYB4OtUzOYJk9scotrEnJxJzGsh/ ------END CERTIFICATE----- -``` - -**步骤三、使用keytool工具打印对应的证书指纹** - -示例 - -``` -keytool -printcert -file profile.cer -result: -所有者: CN=OpenHarmony Application Release, OU=OpenHarmony Team, O=OpenHarmony, C=CN -发布者: CN=OpenHarmony Application CA, OU=OpenHarmony Team, O=OpenHarmony, C=CN -序列号: 68e0bfcc -生效时间: Tue Feb 02 20:19:31 CST 2021, 失效时间: Fri Dec 31 20:19:31 CST 2049 -证书指纹: - SHA1: E3:E8:7C:65:B8:1D:02:52:24:6A:06:A4:3C:4A:02:39:19:92:D1:F5 - SHA256: 8E:93:86:3F:C3:2E:E2:38:06:0B:F6:9A:9B:37:E2:60:8F:FF:B2:1F:93:C8:62:DD:51:1C:BA:C9:F3:00:24:B5 // 证书指纹,去掉冒号,最终结果为8E93863FC32EE238060BF69A9B37E2608FFFB21F93C862DD511CBAC9F30024B5 -... -``` - - +1. 证书存放在[HarmonyAppProvision文件](../../application-dev/security/app-provision-structure.md)的distribution-certificate字段下,新建profile.cer文件,将证书的内容拷贝到profile.cer文件中。 + + ```json + { + ... + "bundle-info": { + "distribution-certificate": "-----BEGIN CERTIFICATE----\nMIICMzCCAbegAwIBAgIEaOC/zDAMBggqhkjOPQQDAwUAMk..." /证书的内容 + ... + } + ... + } + ``` + +2. 将profile.cer内容换行和去掉换行符。 + ``` + -----BEGIN CERTIFICATE----- + MIICMzCCAbegAwIBAgIEaOC/zDAMBggqhkjOPQQDAwUAMGMxCzAJBgNVBAYTAkNO + MRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh + bTEjMCEGA1UEAxMaT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gQ0EwHhcNMjEwMjAy + MTIxOTMxWhcNNDkxMjMxMTIxOTMxWjBoMQswCQYDVQQGEwJDTjEUMBIGA1UEChML + T3Blbkhhcm1vbnkxGTAXBgNVBAsTEE9wZW5IYXJtb255IFRlYW0xKDAmBgNVBAMT + H09wZW5IYXJtb255IEFwcGxpY2F0aW9uIFJlbGVhc2UwWTATBgcqhkjOPQIBBggq + hkjOPQMBBwNCAATbYOCQQpW5fdkYHN45v0X3AHax12jPBdEDosFRIZ1eXmxOYzSG + JwMfsHhUU90E8lI0TXYZnNmgM1sovubeQqATo1IwUDAfBgNVHSMEGDAWgBTbhrci + FtULoUu33SV7ufEFfaItRzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFPtxruhl + cRBQsJdwcZqLu9oNUVgaMAwGCCqGSM49BAMDBQADaAAwZQIxAJta0PQ2p4DIu/ps + LMdLCDgQ5UH1l0B4PGhBlMgdi2zf8nk9spazEQI/0XNwpft8QAIwHSuA2WelVi/o + zAlF08DnbJrOOtOnQq5wHOPlDYB4OtUzOYJk9scotrEnJxJzGsh/ + -----END CERTIFICATE----- + ``` + +3. 使用keytool工具,执行以下命令获取对应的证书指纹。 + + > 说明:keytool工具可以在DevEco Studio安装后的`\tools\openjdk\bin`目录中获取。 + + ```shell + keytool -printcert -file profile.cer + + # 运行结果举例 + # result: + # 所有者: CN=OpenHarmony Application Release, OU=OpenHarmony Team, O=OpenHarmony, C=CN + # 发布者: CN=OpenHarmony Application CA, OU=OpenHarmony Team, O=OpenHarmony, C=CN + # 序列号: 68e0bfcc + # 生效时间: Tue Feb 02 20:19:31 CST 2021, 失效时间: Fri Dec 31 20:19:31 CST 2049 + # 证书指纹: + # SHA1: E3:E8:7C:65:B8:1D:02:52:24:6A:06:A4:3C:4A:02:39:19:92:D1:F5 + # SHA256: 8E:93:86:3F:C3:2E:E2:38:06:0B:F6:9A:9B:37:E2:60:8F:FF:B2:1F:93:C8:62:DD:51:1C:BA:C9:F3:00:24:B5 // 证书指纹,去掉冒号,最终结果为8E93863FC32EE238060BF69A9B37E2608FFFB21F93C862DD511CBAC9F30024B5 + # ... + ``` #### install_list.json中配置 -``` +```json { "install_list" : [ { @@ -165,6 +158,3 @@ result: ] } ``` - - - -- GitLab