HarmonyOS学习(十一)——安全管理

文章目录

官方文档地址: 应用权限管控概述-应用权限管控-程序访问控制-安全-系统 - 华为HarmonyOS开发者 (huawei.com)

1、权限等级划分

根据权限对于不同等级应用有不同的开放范围,权限类型对应分为以下三个等级,等级依次提高

APL级别 说明 开放范围
normal 允许应用访问超出默认规则外的普通系统资源,如配置Wi-Fi信息、调用相机拍摄等。 这些系统资源的开放(包括数据和功能)对用户隐私以及其他应用带来的风险低。 APL等级为normal及以上的应用。
system_basic 允许应用访问操作系统基础服务(系统提供或者预置的基础功能)相关的资源,如系统设置、身份认证等。 这些系统资源的开放对用户隐私以及其他应用带来的风险较高。 - APL等级为system_basic及以上的应用。 - 部分权限对normal级别的应用受限开放,这部分权限在本指导中描述为"受限开放权限"。
system_core 涉及开放操作系统核心资源的访问操作。这部分系统资源是系统最核心的底层服务,如果遭受破坏,操作系统将无法正常运行。 - APL等级为system_core的应用。 - 仅对系统应用开放。
2、权限类型

根据授权方式的不同,权限类型可分为system_grant(系统授权)和user_grant(用户授权)

system_grant(系统授权)

system_grant指的是系统授权类型,在该类型的权限许可下,应用被允许访问的数据不会涉及到用户或设备的敏感信息,应用被允许执行的操作对系统或者其他应用产生的影响可控。

如果在应用中申请了system_grant权限,那么系统会在用户安装应用时,自动把相应权限授予给应用。

user_grant(用户授权)

user_grant指的是用户授权类型,在该类型的权限许可下,应用被允许访问的数据将会涉及到用户或设备的敏感信息,应用被允许执行的操作可能对系统或者其他应用产生严重的影响。

该类型权限不仅需要在安装包中申请权限,还需要在应用动态运行时,通过发送弹窗的方式请求用户授权。在用户手动允许授权后,应用才会真正获取相应权限,从而成功访问操作目标对象。

3、动态申请权限列表单
权限名称 权限级别 权限说明
ohos.permission.ANSWER_CALL system_basic 允许应用接听来电
ohos.permission.READ_CALENDAR system_basic 允许应用读取日历信息
ohos.permission.READ_CALL_LOG system_basic 允许应用读取通话记录
ohos.permission.READ_CELL_MESSAGE system_basic 允许应用读取设备收到的广播信息
ohos.permission.READ_CONTACTS system_basic 允许应用读取联系人护具
ohos.permission.READ_MESSAGE system_basic 允许应用读取短信息
ohos.permission.RECEIVE_MMS system_basic 允许应用接受和处理彩信
ohos.permission.RECEIVE_SMS system_basic 允许应用接受和处理短信
ohos.permission.RECEIVE_WAP_MESSAGE system_basic 允许应用接收和处理Wap消息
ohos.permission.MICROPHONE normal 允许应用使用麦克风
ohos.permission.SEND_MESSAGE system_basic 允许应用发送短信
ohos.permission.WRITE_CALENDAR normal 允许应用添加、移除或者更改日历活动
ohos.permission.WRITE_CALL_LOG system_basic 允许应用添加、移除或更改通话记录
ohos.permission.WRITE_CONTACTS system_basic 允许应用添加、移除或者更改联系人数据
ohos.permission.DISTRIBUTED_DATASYNC normal 允许不同设备间的数据交换
ohos.permission.MANAGE_VOICEMAIL system_basic 允许应用在语音信箱中留言
ohos.permission.LOCAL_IN_BACKGROUND normal 允许应用在后台运行时获取设备位置信息
ohos.permission.LOCATION normal 允许应用获取设备位置信息
ohos.permission.APPROXIMATELY_LOCATION normal 允许应用获取设备模糊位置信息
ohos.permission.MEDIA_LOCATION normal 允许应用访问用户媒体文件中的地理位置信息
ohos.permission.CAMERA normal 允许应用使用相机拍摄照片和录制视频
ohos.permission.READ_MEDIA normal 允许应用读取用户外部存储中的媒体文件信息
ohos.permission.WRITE_MEDIA normal 允许应用读写用户外部存储中的媒体文件信息
ohos.permission.ACTIVITY_MOTION normal 允许应用读取用户当前的运动状态
ohos.permission.READ_HEALTH_DATA normal 允许应用读取用户的健康数据
4、访问控制开发步骤

如果应用需要获取目标权限,需要先进行权限申请。

  • 权限申请:开发者需要在配置文件中声明目标权限。
  • 权限授权:如果目标权限是system_grant类型,开发者在进行权限申请后,系统会在安装应用时为其进行权限授予,开发者不需要进行其他操作即可使用权限。如果目标权限是user_grant时,开发者在进行权限申请后,在运行时触发动态弹窗,请求用户授权。
4.1、权限申请

应用需要在工程配置文件中对需要的权限逐个神功,没有在配置文件中声明的权限,应用将无法获得授权。

plain 复制代码
{
  "module":{
    "requestPermissions": [
        {
          "name": "ohos.permission.INTERNET",
          "reason":"$string:Permission_internet_reason",
          "usedScene": {
              "abilities": ["PermissionDemoAbility"],
              "when": "inuse"
          }
        },
        {
          "name": "ohos.permission.CAMERA",
          "reason": "$string:Permission_camera_reason",
          "usedScene": {
            "abilities": ["PermissionDemoAbility"],
            "when": "always"
          }
        }
    ]
  }
}
name 权限名称
reason 当申请权限为user_grant时,此字段必填,描述申请权限的原因
usedscreen 当申请权限为user_grant时,此字段必填,描述权限使用的场景和时机
abilities 标识需要使用该权限的Ability,为数组
when 标识权限使用的时机,inuse/always,标识仅允许前台使用和前后台都可以使用
5、实战:访问Camera授权
5.1、申请ohos.permission.Camera权限
plain 复制代码
{
  "name": "ohos.permission.CAMERA",
  "reason": "$string:Permission_camera_reason",
  "usedScene": {
    "abilities": ["PermissionDemoAbility"],
    "when": "always"
  }
}
5.2、校验当前是否已经授权

在进行权限申请之前,需要先检查当前应用程序是否已经被授予权限。可以通过调用checkAccessToken()方法来校验当前是否已经授权。如果已经授权,则可以直接访问目标操作,否则需要进行下一步操作,即向用户申请授权。

checkAccessToken(tokenID: number, permissionName: Permissions): Promise

参数名 类型 必填 说明
tokenID number 要校验的目标应用的身份标识。可通过应用的ApplicationInfo的accessTokenId字段获得。
permissionName Permissions 需要校验的权限名称,合法的权限名取值可在应用权限列表中查询。
plain 复制代码
const permissions:Array<Permissions> = ["ohos.permission.CAMERA"]

//检查权限
async function checkPermissionGrant(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;

  // 获取应用程序的accessTokenID
  let tokenId: number = 0;
  try {
    let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
    tokenId = appInfo.accessTokenId;
  } catch (error) {
    // @ts-ignore
    const err: BusinessError = error as BusinessError;
    console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
  }

  // 校验应用是否被授予权限
  try {
    grantStatus = await atManager.checkAccessToken(tokenId, permission);
  } catch (error) {
    // @ts-ignore
    const err: BusinessError = error as BusinessError;
    console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
  }

  return grantStatus;
}

async function checkPermissions(): Promise<void> {
  let grantStatus: abilityAccessCtrl.GrantStatus = await checkPermissionGrant(permissions[0]);

  if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
    // 已经授权,可以继续访问目标操作
    hilog.error(0x0000,'check_permission',"获取到Camera权限")
  } else {
    // 申请麦克风权限
    hilog.error(0x0000,'check_permission',"Camera权限未被授予")
  }
}
5.3、请求权限
plain 复制代码
// 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
  atManager.requestPermissionsFromUser(context, permissions).then((data) => {
    let grantStatus: Array<number> = data.authResults;
    let length: number = grantStatus.length;
    for (let i = 0; i < length; i++) {
      if (grantStatus[i] === 0) {
        // 用户授权,可以继续访问目标操作
      } else {
        // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
        return;
      }
    }
    // 授权成功
    // @ts-ignore
  }).catch((err: BusinessError) => {
    console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
  })
}
5.4、在UI中进行权限声明
plain 复制代码
import common from '@ohos.app.ability.common';
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';



const permissions: Array<Permissions> = ['ohos.permission.CAMERA'];
// 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
  atManager.requestPermissionsFromUser(context, permissions).then((data) => {
    let grantStatus: Array<number> = data.authResults;
    let length: number = grantStatus.length;
    for (let i = 0; i < length; i++) {
      if (grantStatus[i] === 0) {
        // 用户授权,可以继续访问目标操作
      } else {
        // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
        return;
      }
    }
    // 授权成功
    // @ts-ignore
  }).catch((err: BusinessError) => {
    console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
  })
}


@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

  aboutToAppear() {
    // 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
    const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
    reqPermissionsFromUser(permissions, context);
  }

  build() {

    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}
相关推荐
Red Red3 小时前
网安基础知识|IDS入侵检测系统|IPS入侵防御系统|堡垒机|VPN|EDR|CC防御|云安全-VDC/VPC|安全服务
网络·笔记·学习·安全·web安全
2401_857610034 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
Natural_yz4 小时前
大数据学习17之Spark-Core
大数据·学习·spark
qq_172805595 小时前
RUST学习教程-安装教程
开发语言·学习·rust·安装
一只小小汤圆5 小时前
opencascade源码学习之BRepOffsetAPI包 -BRepOffsetAPI_DraftAngle
c++·学习·opencascade
踏雪Vernon5 小时前
[OpenHarmony5.0][Docker][环境]OpenHarmony5.0 Docker编译环境镜像下载以及使用方式
linux·docker·容器·harmonyos
虾球xz5 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
LateBloomer7775 小时前
FreeRTOS——信号量
笔记·stm32·学习·freertos
legend_jz5 小时前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
Komorebi.py5 小时前
【Linux】-学习笔记04
linux·笔记·学习