在HarmonyOS生态中,保障用户隐私和安全是至关重要的设计原则之一。为此,HarmonyOS引入了AccessTokenManager (ATM)作为统一的应用权限管理机制,确保应用在访问系统资源、数据以及与其他应用交互时遵循严格的安全策略。本文将详细介绍ATM的工作原理、权限申请与校验流程,并提供相关代码示例,帮助开发者在HarmonyOS平台上构建安全合规的应用。
ATM概述
ATM基于AccessToken实现,每个应用都有一个独一无二的TokenID,作为其身份标识。ATM利用TokenID来管理应用的权限,确保应用只能在拥有适当权限的情况下访问或操作受保护的资源。
权限保护对象
- 数据:涵盖个人数据(如照片、联系人)、设备数据(如设备ID)、应用数据。
- 功能:包括设备功能(如通话、网络访问)和应用功能(如悬浮窗、快捷方式创建)。
权限使用原则
- 明确性:权限申请需附带清晰的使用场景和目的说明。
- 最小化:仅申请业务功能所必需的权限。
- 适时申请:在实际需要权限时动态申请,避免首次启动时频繁弹窗。
- 用户体验:尊重用户选择,若权限被拒,不影响应用基本功能。
- 系统权限列表:应用权限需从官方定义的权限列表中选取。
权限工作流程
权限申请使用流程
- 需求评估:确认操作是否需要特定权限。
- 权限申请:在安装包中声明需要的权限。
- 用户授权:对于用户授权类权限,使用弹窗请求用户同意。
- 权限使用:授权后,应用可执行相应操作。
权限校验流程
- 接口保护:根据接口敏感度选择合适权限进行保护。
- 访问控制:通过ATM权限校验接口验证访问者权限。
- 权限通过:访问者拥有权限后,可正常使用接口功能。
权限等级与类型
权限等级
- normal:普通权限,风险较小。
- system_basic:涉及系统基础服务,风险中等。
- system_core:操作系统核心权限,暂不对第三方应用开放。
权限类型
- system_grant:系统自动授权,无需用户介入。
- user_grant:需用户明确同意,涉及敏感操作。
示例
HarmonyOS应用的权限体系涉及应用的APL(Ability Privilege Level)等级和权限类型。应用权限管理遵循严格的访问控制原则,确保应用仅在拥有必要权限的前提下访问资源。
配置文件权限声明
Stage模型
在module.json5
中声明权限:
1{
2 "module" : {
3 // ...
4 "requestPermissions":[
5 {
6 "name" : "ohos.permission.PERMISSION_NAME",
7 "reason": "$string:reason_for_permission",
8 "usedScene": {
9 "abilities": [
10 "YourAbility"
11 ],
12 "when":"inuse"
13 }
14 }
15 ]
16 }
17}
FA模型
在config.json
中声明权限:
1{
2 "module" : {
3 // ...
4 "reqPermissions":[
5 {
6 "name" : "ohos.permission.PERMISSION_NAME",
7 "reason": "$string:reason_for_permission",
8 "usedScene": {
9 "ability": [
10 "YourAbility"
11 ],
12 "when":"inuse"
13 }
14 }
15 ]
16 }
17}
权限校验与动态申请
校验权限
1 import bundleManager from '@ohos.bundle.bundleManager';
2 import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
3
4 async function checkPermission(permission) {
5 let atManager = abilityAccessCtrl.createAtManager();
6 let tokenId;
7
8 try {
9 let bundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
10 tokenId = bundleInfo.appInfo.accessTokenId;
11 } catch (err) {
12 console.error(`Error fetching accessTokenId: ${err}`);
13 }
14
15 try {
16 let grantStatus = await atManager.checkAccessToken(tokenId, permission);
17 return grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
18 } catch (err) {
19 console.error(`Permission check failed: ${err}`);
20 }
21 return false;
22}
动态申请权限(通用示例)
1 import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
2 import common from '@ohos.app.ability.common';
3
4 async function requestPermission(context, permissions) {
5 let atManager = abilityAccessCtrl.createAtManager();
6
7 try {
8 let result = await atManager.requestPermissionsFromUser(context, permissions);
9 let authResults = result.authResults;
10
11 for (let i = 0; i < authResults.length; i++) {
12 if (authResults[i] !== 0) {
13 // 用户未授权,处理逻辑
14 return false;
15 }
16 }
17 // 所有权限均被授权
18 return true;
19 } catch (err) {
20 console.error(`Permission request failed: ${err}`);
21 return false;
22 }
23}
动态申请授权示例
在UIAbility中申请
1export default class YourAbility extends UIAbility {
2 onWindowStageCreate(windowStage) {
3 const permissions = ['ohos.permission.PERMISSION_NAME'];
4 this.requestPermissions(permissions);
5 }
6
7 async requestPermissions(permissions) {
8 let context = this.context;
9 if (await requestPermission(context, permissions)) {
10 // 权限申请成功,执行相关操作
11 } else {
12 // 引导用户至设置页开启权限
13 openPermissionsInSystemSettings();
14 }
15 }
16}
引导用户至系统设置
1 function openPermissionsInSystemSettings(context) {
2 let wantInfo = {
3 action: 'action.system.settings.permission',
4 entities: ['com.example.yourapp']
5 };
6 context.startAbility(wantInfo);
7}
// 假设需要请求麦克风权限
String permission = "ohos.permission.MICROPHONE";
// 检查当前是否已有权限
int result = checkSelfPermission(permission);
if (result == PackageManager.PERMISSION_GRANTED) {
// 已有权限,执行操作
} else {
// 未授权,发起请求
requestPermissions(new String[]{permission}, PERMISSION_REQUEST_CODE);
}
// 处理权限请求结果
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 用户已授权,执行操作
} else {
// 用户拒绝授权,给出提示或处理方案
}
}
}
总结
通过深入了解和正确应用AccessTokenManager及其权限管理机制,开发者能够在HarmonyOS平台上构建既强大又安全的应用,确保用户数据的隐私与应用生态的健康发展。遵循权限使用的最佳实践,是每个HarmonyOS开发者不可或缺的责任。