更多信息请访问:与华为官方共建的鸿蒙技术社区https://harmonyos.51cto.com1.简介安全子系统是OpenHarmony提供的能力有效保护应用程序和用户数据。主要功能:系统安全、数据安全、应用安全等;目前开源功能:应用完整性保护、应用权限管理、设备鉴权、密钥管理服务、数据分级保护;应用权限管理:为程序框架子系统功能提供权限管理,为上层应用提供权限申请和授权状态查询接口。本文将介绍标准体系下安全子系统的应用权限管理部分在系统中是如何适配和实现的,并尝试深入细节。1.1OpenHarmony架构图1.2安全子系统1.3应用权限管理在OpenHarmony中,应用和系统服务运行在独立的沙箱中,进程空间和程序数据相互隔离,保护应用数据的安全;但是,它们在独立的沙箱中运行。沙箱中的服务或应用程序也需要提供一些API来实现所需的功能。当其他独立沙箱中的应用程序跨进程访问这些API时,系统需要提供权限管理机制对这些API的访问者进行授权。应用权限管理提供了一种权限定义机制,允许系统服务和应用程序为自己的敏感API定义新的权限。其他应用必须申请此权限才能访问此敏感API;应用权限管理提供了一种权限申请机制,允许应用程序申请权限。这些权限由系统或其他应用程序定义。权限申请通过后,您可以访问系统提供的敏感API或其他与此权限相关的应用;应用权限管理也为用户提供了一些必要的功能,方便用户查看和管理权限的授予。2.基础知识2.1代码结构/base/security/permission├──frameworks#Infrastructurelayer│└──permission_standard#标准系统权限管理基础设施层├──interfaces#接口层│├──innerkits#内部接口层││├──permission_lite#轻量级系统,小系统权限管理内部接口层││└──permission_standard#标准系统权限管理内部接口层│└──kits#外部接口层│├──permission_lite#轻量级系统,小系统权限管理对外接口层│└──permission_standard#标准系统权限管理对外接口层└──services#服务层├──permission_lite#轻量级系统,小型系统权限管理服务层└──permission_standard#标准系统权限管理服务层2.2SystemAbility应用权限管理模块以SystemAbility的形式提供能力。在分布式任务调度子系统中,safwk组件定义了SystemAbility在OpenHarmony中的实现方法,并提供启动、注册等接口实现。实现一个SystemAbility需要六个步骤:1)定义服务namespaceOHOS{classIListenAbility:publicIRemoteBroker{public:virtualintAddVolume(intvolume)=0;public:enum{ADD_VOLUME=1,};public:DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.test.IListenAbility");};}2)定义客户端通信代码私人:staticinlinebrokerdelegator委托人_;};}//namespaceOhos3)定义定义服务代码代码代码xxxstubnamespaceohos{int32_tlistenenabilitystub::onremoteRequest::onremoterequest(onremoterequest)data.ReadInt32()));}default:returnIPCObjectStub::OnRemoteRequest(code,data,reply,option);}}}4)SystemAbility实现类命名空间{constexprOHOS::HiviewDFX::HiLogLabelLABEL={LOG_CORE,0xD001800,"SA_TST"};}REGISTER_SYSTEM_ABILITY_BY_ID(ListenAbility,DISTRIBUTED_SCHED_TEST_LISTEN_ID,true);ListenAbility::ListenAbility(int32_tsaId,boolrunOnCreate):SystemAbility(saId,runOnCreate){HiLog::信息(LABEL,":%scalled",__func__);HiLog::Info(LABEL,"ListenAbility()");}ListenAbility::~ListenAbility(){HiLog::Info(LABEL,"~ListenAbility()");}intListenAbility::AddVolume(intvolume){pid_tcurrent=getpid();HiLog::Info(LABEL,"ListenAbility::AddVolumevolume=%d,pid=%d.",volume,current);return(volume+1);}voidListenAbility::OnDump(){}voidListenAbility::OnStart(){HiLog::Info(LABEL,"ListenAbility::OnStart()");HiLog::Info(LABEL,"ListenAbility:%scalled:-----Publish------",__func__);boolres=Publish(this);if(res){HiLog::Error(LABEL,"ListenAbility:res==false");}HiLog::Info(LABEL,"ListenAbility:%scalled:AddAbilityListener_OS_TST----求-----",__func__);AddSystemAbilityListener(DISTRIBUTED_SCHED_TEST_OS_ID);HiLog::Info(LABEL,"ListenAbility:%scalled:AddAbilityListener_OS_TST----end-----",__func__);HiLog::Info(LABEL,"ListenAbility:%scalled:StopAbility_OS_TST----beg-----",__func__);StopAbility(DISTRIBUTED_SCHED_TEST_OS_ID);HiLog::Info(LABEL,"ListenAbility:%scalled:StopAbility_OS_TST----end-----",__func__);return;}voidListenAbility::OnStop(){5)SystemAbility配置c++实现的SA必须配置相关SystemAbilityprofile配置文件才能完成SA加载注册逻辑,否则没有profile配置的SystemAbility将无法完成注册配置方法如下:在子系统的根目录下创建一个名为sa_profile的文件夹;然后在该文件夹下创建两个文件:一个是一个以serviceId为前缀的xml文件;另一个是BUILD.gn文件listen_testserviceid/system/lib64/liblistentest.z.sotruefalse1BUILD.gn:import("//build/ohos/sa_profile/sa_profile.gni")ohos_sa_profile("xxx_sa_profile"){sources=["serviceid.xml"]subsystem_name="distributedschedule"}6)rc配置文件rc配置文件由linux提供原生进程上拉策略用于在手机启动阶段拉取init进程配置的rc文件用户程序框架子系统提供了基础验证能力权限管理,不对第三方应用开??放,提供如下API。3.内部实现3.1类间关系IPermissionManager:内部接口类PermissionManagerProxy:IPC请求代理类功能服务类,调用PermissionStateManager和PermissionDefinitionManagerPermissionStateManager:真实应用权限管理功能实现PermissionDefinitionManager:真实应用权限管理功能实现3.2下的应用权限管理功能内部逻辑标准体系是基于SAMgr管理框架实现的,如何配置SAMgr框架见基础知识介绍,想了解更多细节请参考SAMgr相关学习。这里着重介绍应用权限管理功能部分,对代码逻辑的关键节点进行分析展示。应用权限管理组件通过单例模式的PermissionKit类提供接口。PermissionKit类的内部接口函数调用PermissionManagerClient类,PermissionManagerClient通过调用GetSystemAbility函数获取注册到SAMgr的代理类单例PermissionManagerProxy。代码如下:GetSystemAbilityManagerisnull",__func__);returnnullptr;}//获取ProxyautopermissionSa=sam->GetSystemAbility(IPermissionManager::SA_ID_PERMISSION_MANAGER_SERVICE);if(permissionSa==nullptr){PERMISSION_LOG_DEBUG(LABEL,"%{public}s:GetSystemAbility%{__public}fnull",IPermissionManager::SA_ID_PERMISSION_MANAGER_SERVICE);returnnullptr;}autoproxy=iface_cast(permissionSa);if(proxy==nullptr){PERMISSION_LOG_DEBUG(LABEL,"%{public}s:iface_castgetrenull",__func__)trpron;}获得代理类PermissionManagerProxy后,PermissionManagerProxy内部的不同功能接口函数会调用SendRequest函数发起IPC请求服务。示例代码如下(删除省略部分):intPermissionManagerProxy::VerifyPermission(conststd::string&bundleName,conststd::string&permissionName,intuserId){//省略部分.............................//发送请求服务int32_trequestResult=remote->SendRequest(static_cast(IPermissionManager::InterfaceCode::VERIFY_PERMISSION),data,reply,option);if(requestResult!=NO_ERROR){PERMISSION_LOG_ERROR(LABEL,"%{public}ssendrequestfail,result:%{public}d",__func__,requestResult);returnPERMISSION_NOT_GRANTED;}int32_tresult=reply.ReadInt32();PERMISSION_LOG_DEBUG(LABEL,"%{public}sgetresultfromserverdata=%{public}d“,__func__,结果);returnresult;}接口类IPermissionManager定义了IPC通信的请求码。示例代码如下(删去省略部分):classIPermissionManager:publicIRemoteBroker{public:staticconstintSA_ID_PERMISSION_MANAGER_SERVICE=3501;DECLARE_INTERFACE_DESCRIPTOR(u"ohos.security.permission.IPermissionManager");virtualintVerifyPermission(conststd::string&bundleName,conststd::string&permissionName,intuserId)=0;//省略部分......................//请求码enumclassInterfaceCode{VERIFY_PERMISSION=0xff01,CAN_REQUEST_PERMISSION=0xff02,GRANT_USER_GRANTED_PERMISSION=0xff03,GRANT_SYSTEM_GRANTED_PERMISSION=0xff04,REVOKE_USER_GRANTED_PERMISSION=0xff05,REVOKE_SYSTEM_GRANTED_PERMISSION=0xff06,ADD_USER_GRANTED_REQ_PERMISSIONS=0xff07,ADD_SYSTEM_GRANTED_REQ_PERMISSIONS=0xff08,REMOVE_USER_GRANTED_REQ_PERMISSIONS=0xff09,REMOVE_SYSTEM_GRANTED_REQ_PERMISSIONS=0xff10,ADD_DEF_PERMISSIONS=0xff11,REMOVE_DEF_PERMISSIONS=0xff12,GET_DEF_PERMISSION=0xff13,};};PermissionManagerServiceSincetheclassinheritsPermissionManagerStub,itwillreceivethedifferentinformationsent由代理PermissionManagerProxy通过IPC通信接口函数中的OnRemoteRequest函数。请求处理示例代码如下:int32_tPermissionManagerStub::OnRemoteRequest(uint32_tcode,MessageParcel&data,MessageParcel&reply,MessageOption&option){PERMISSION_LOG_INFO(LABEL,"%{public}scalled,code:%{public}d",__func__,code);std::u16stringdescriptor=data.ReadInterfaceToken();if(descriptor!=IPermissionManager::GetDescriptor()){PERMISSION_LOG_ERROR(LABEL,"getunexpectdescriptor:%{public}s",Str16ToStr8(descriptor).c_str());returnRET_FAILED;}开关(代码){casestatic_cast(IPermissionManager::InterfaceCode::VERIFY_PERMISSION):VerifyPermissionInner(数据,回复);中断;casestatic_castIPermissionManager::InterfaceCode::GRANT_USER_GRANTED_PERMISSION):GrantUserGrantedPermissionInner(data,reply);break;//省略部分......默认:returnIPCObjectStub::OnRemoteRequest(code,data,reply,option);}returnNO_ERROR;}最后,PermissionManagerService调用PermissionStateManager和PermissionDefinitionManager类提供的函数来实现具体的功能。4.小结如今的设备安全问题越来越受到不同行业的关注。OpenHarmney安全子系统是系统的基本能力之一。开发设备系统的安全性尤为重要。对于系统框架的开发,需要学习其内部原理,深入理解代码结构。本文档介绍了标准体系下应用权限管理的相关逻辑框架。随着学习的深入,会不断完善对安全子系统的解释。更多信息请访问:Harmonyos.51cto.com,与华为官方合作打造的鸿蒙技术社区