accesstoken-guidelines.md 11.5 KB
Newer Older
1
# 访问控制授权申请
L
l00520400 已提交
2 3 4

## 场景介绍

5
[应用的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)
L
l00520400 已提交
6

7
本文将从如下场景分别介绍:
8

9
- [配置文件权限声明](#配置文件权限声明)
10
- [ACL方式声明](#acl方式声明)
11 12
- [向用户申请授权](#向用户申请授权)
- [user_grant权限预授权](#user_grant权限预授权)
13

14
## 配置文件权限声明
Z
zengyawen 已提交
15

16
应用需要在工程配置文件中,对需要的权限逐个声明,未在配置文件中声明的权限,应用将无法获得授权。OpenHarmony提供了两种应用模型,分别为FA模型和Stage模型,更多信息可以参考[应用模型解读](../application-models/application-model-description.md)。不同的应用模型的应用包结构不同,所使用的配置文件不同。
17

18 19
> **说明**:应用默认的APL等级为`normal`,当应用需要申请`system_basic`和`system_core`等级时,除了在配置文件中进行权限声明之外,还需要通过[ACL方式](#acl方式声明)进行声明使用。

20
配置文件标签说明如下表所示。
21

22 23 24
| 标签      | 是否必填 | 说明                                                         |
| --------- | -------- | ------------------------------------------------------------ |
| name      | 是       | 权限名称。                                                   |
25 26
| reason    | 否       | 描述申请权限的原因。<br />> **说明**:当申请的权限为user_grant权限时,此字段必填。 |
| usedScene | 否       | 描述权限使用的场景和时机。<br />> **说明**:当申请的权限为user_grant权限时,此字段必填。 |
27 28
| abilities | 否       | 标识需要使用到该权限的Ability,标签为数组形式。<br/>**适用模型**:Stage模型 |
| ability   | 否       | 标识需要使用到该权限的Ability,标签为数组形式。<br/>**适用模型**:FA模型 |
29
| when      | 否       | 标识权限使用的时机,值为`inuse/always`<br />- inuse:表示为仅允许前台使用。<br />- always:表示前后台都可使用。 |
30

31
### Stage模型
32

33
使用Stage模型的应用,需要在[module.json5配置文件](../quick-start/module-configuration-file.md)中声明权限。
34

F
update  
fanchenxuan 已提交
35 36
```json
{
37
  "module" : {
38 39
    // ...
    "requestPermissions":[
40 41 42 43
      {
        "name" : "ohos.permission.PERMISSION1",
        "reason": "$string:reason",
        "usedScene": {
44
          "abilities": [
45 46 47 48 49 50 51 52 53
            "FormAbility"
          ],
          "when":"inuse"
        }
      },
      {
        "name" : "ohos.permission.PERMISSION2",
        "reason": "$string:reason",
        "usedScene": {
54
          "abilities": [
55 56 57 58 59 60 61
            "FormAbility"
          ],
          "when":"always"
        }
      }
    ]
  }
F
update  
fanchenxuan 已提交
62 63 64
}
```

65
### FA模型
F
update  
fanchenxuan 已提交
66

67
使用FA模型的应用,需要在config.json配置文件中声明权限。
F
update  
fanchenxuan 已提交
68

69 70
```json
{
71
  "module" : {
72 73
    // ...
    "reqPermissions":[
74 75 76 77
      {
        "name" : "ohos.permission.PERMISSION1",
        "reason": "$string:reason",
        "usedScene": {
78
          "ability": [
79 80 81
            "FormAbility"
          ],
          "when":"inuse"
82 83 84 85 86 87
        }
      },
      {
        "name" : "ohos.permission.PERMISSION2",
        "reason": "$string:reason",
        "usedScene": {
88
          "ability": [
89 90
            "FormAbility"
          ],
91
          "when":"always"
92 93
        }
      }
94
    ]
95
  }
96 97
}
```
F
update  
fanchenxuan 已提交
98

zyjhandsome's avatar
zyjhandsome 已提交
99
## ACL方式声明
100

101
应用在申请`system_basic``system_core`等级权限时,高于应用默认的`normal`等级。当应用需要申请权限项的等级高于应用默认的等级时,需要通过ACL方式进行声明使用。
102 103

例如应用在申请访问用户公共目录下音乐类型的文件,需要申请` ohos.permission.WRITE_AUDIO`权限,该权限为`system_basic`等级;以及应用在申请截取屏幕图像功能,该权限为`system_core`等级,需要申请` ohos.permission.CAPTURE_SCREEN`权限。此时需要将相关权限项配置到[HarmonyAppProvision配置文件](app-provision-structure.md)`acl`字段中。
104

105 106
```json
{
107 108 109
	// ...
	"acls":{
		"allowed-acls":[
110 111
			"ohos.permission.WRITE_AUDIO",
            "ohos.permission.CAPTURE_SCREEN"
112 113
		]
	}
114 115 116
}
```

117
## 向用户申请授权
L
l00520400 已提交
118

119 120
应用需要获取用户的隐私信息或使用系统能力时,例如获取位置信息、访问日历、使用相机拍摄照片或者录制视频等,需要向用户申请授权。此时应用申请的权限包括了`user_grant`类型权限,需要先通过权限校验,判断当前调用者是否具备相应权限。当权限校验结果显示当前应用尚未被授权该权限时,再通过动态弹框授权方式给用户提供手动授权入口。示意效果如下图所示。
<img src="figures/permission-read_calendar.jpeg" width="40%;" />
121

122
> **说明**:每次访问受目标权限保护的接口前,都需要调用[requestPermissionsFromUser()](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9)接口请求权限,用户在动态授予后可能通过设置取消应用的权限,因此不能把之前授予的授权状态持久化。
123

124
### Stage模型
125

126 127
以允许应用读取日历信息为例进行说明。

128
1. 申请`ohos.permission.READ_CALENDAR`权限,配置方式请参见[访问控制授权申请](#配置文件权限声明)
129 130

2. 可以在UIAbility的onWindowStageCreate()回调中调用[requestPermissionsFromUser()](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9)接口动态申请权限,也可以根据业务需要在UI界面中向用户申请授权。根据[requestPermissionsFromUser()](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9)接口返回值判断是否已获取目标权限,如果当前已经获取权限,则可以继续正常访问目标接口。
zyjhandsome's avatar
zyjhandsome 已提交
131
   
132
   在UIAbility中动态申请授权。
zyjhandsome's avatar
zyjhandsome 已提交
133
   
134 135
   ```typescript
   import UIAbility from '@ohos.app.ability.UIAbility';
136
   import window from '@ohos.window';
137
   import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
138 139 140 141
   
   export default class EntryAbility extends UIAbility {
       // ...
   
142
       onWindowStageCreate(windowStage: window.WindowStage) {
143 144
           // Main window is created, set main page for this ability
           let context = this.context;
145
           let atManager = abilityAccessCtrl.createAtManager();
146 147
           // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
           const permissions: Array<Permissions> = ['ohos.permission.READ_CALENDAR'];
148
           atManager.requestPermissionsFromUser(context, permissions).then((data) => {
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
               console.info(`[requestPermissions] data: ${JSON.stringify(data)}`);
               let grantStatus: Array<number> = data.authResults;
               if (grantStatus[0] === -1) {
                   // 授权失败
               } else {
                   // 授权成功
               }
           }).catch((err) => {
               console.error(`[requestPermissions] Failed to start request permissions. Error: ${JSON.stringify(err)}`);
           })
           
           // ...
       }
   }
   ```
zyjhandsome's avatar
zyjhandsome 已提交
164
   
165 166
   在UI界面中向用户申请授权。
   ```typescript
167
   import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
168 169 170 171 172 173 174
   import common from '@ohos.app.ability.common';
   
   @Entry
   @Component
   struct Index {
     reqPermissions() {
       let context = getContext(this) as common.UIAbilityContext;
175
       let atManager = abilityAccessCtrl.createAtManager();
176 177
       // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
       const permissions: Array<Permissions> = ['ohos.permission.READ_CALENDAR'];
178
       atManager.requestPermissionsFromUser(context, permissions).then((data) => {
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
         console.info(`[requestPermissions] data: ${JSON.stringify(data)}`);
         let grantStatus: Array<number> = data.authResults;
         if (grantStatus[0] === -1) {
           // 授权失败
         } else {
           // 授权成功
         }
       }).catch((err) => {
         console.error(`[requestPermissions] Failed to start request permissions. Error: ${JSON.stringify(err)}`);
       })
     }
   
     // 页面展示
     build() {
       // ...
     }
   }
   ```
197

198
### FA模型
L
l00520400 已提交
199

200
通过调用[requestPermissionsFromUser()](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7)接口向用户动态申请授权。
L
l00520400 已提交
201 202

```js
F
fanchenxuan 已提交
203 204 205 206
import featureAbility from '@ohos.ability.featureAbility';

reqPermissions() {
    let context = featureAbility.getContext();
F
fanchenxuan 已提交
207 208
    let array:Array<string> = ["ohos.permission.PERMISSION2"];
    //requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
F
fanchenxuan 已提交
209
    context.requestPermissionsFromUser(array, 1).then(function(data) {
210 211 212
        console.log("data:" + JSON.stringify(data));
        console.log("data permissions:" + JSON.stringify(data.permissions));
        console.log("data result:" + JSON.stringify(data.authResults));
F
fanchenxuan 已提交
213
    }, (err) => {
214
        console.error('Failed to start ability', err.code);
F
fanchenxuan 已提交
215
    });
216
}
L
l00520400 已提交
217
```
218 219
## 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`
220

221 222
- `bundleName`字段配置为应用的Bundle名称。
- `app_signature`字段配置为应用的指纹信息。指纹信息的配置参见[应用特权配置指南](../../device-dev/subsystems/subsys-app-privilege-config-guide.md#install_list_capabilityjson中配置)
zyjhandsome's avatar
zyjhandsome 已提交
223
- `permissions`字段中`name`配置为需要预授权的`user_grant`类型的权限名;`permissions`字段中`userCancellable`表示为用户是否能够取消该预授权,配置为true,表示支持用户取消授权,为false则表示不支持用户取消授权。
224

225
> **说明**:当前仅支持预置应用配置该文件。
L
lsq 已提交
226 227 228

```json
[
229
  // ...
L
lsq 已提交
230
  {
231 232
    "bundleName": "com.example.myapplication", // Bundle名称
    "app_signature": ["****"], // 指纹信息
L
lsq 已提交
233 234
    "permissions":[
      {
235 236
        "name": "ohos.permission.PERMISSION_X", // user_grant类型预授权的权限名
        "userCancellable": false // 用户不可取消授权
L
lsq 已提交
237 238
      },
      {
239 240
        "name": "ohos.permission.PERMISSION_Y", // user_grant类型预授权的权限名
        "userCancellable": true // 用户可取消授权
L
lsq 已提交
241 242 243 244 245
      }
    ]
  }
]
```
246

247 248 249 250
## 相关实例

针对访问控制,有以下相关实例可供参考:

251 252
- [AbilityAccessCtrl:访问权限控制(ArkTS)(Full SDK)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/master/Safety/AbilityAccessCtrl)
- [为应用添加运行时权限(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Ability/AccessPermission)