赞
踩
代码路径:security_access_token: ATM(AccessTokenManager)是OpenHarmony上基于AccessToken构建的统一的应用权限管理能力。
ATM(AccessTokenManager)是OpenHarmony上基于AccessToken构建的统一的应用权限管理能力。
应用的Accesstoken信息主要包括应用身份标识APPID、用户ID,应用分身索引、应用APL(Ability Privilege Level)等级、应用权限信息等。每个应用的Accestoken信息由一个32bits的设备内唯一标识符TokenID(Token identity)来标识。
ATM模块主要提供如下功能:
- /base/security/access_token
- ├── frameworks # 框架层,基础功能代码存放目录
- │ ├── accesstoken # Accesstoken管理框架代码存放目录
- │ ├── tokensync # Accesstoken信息同步框架代码存放目录
- │ └── common # 框架公共代码存放目录
- ├── interfaces # 接口层
- │ └── innerkits # 内部接口层
- │ ├── accesstoken # Accesstoken内部接口代码存放目录
- │ ├── nativetoken # nativetoken内部接口代码存放目录
- │ └── tokensync # Accesstoken信息同步内部接口代码存放目录
- └── services # 服务层
- ├── accesstokenmanager # Accesstoken管理服务代码存放目录
- └── tokensyncmanager # Accesstoken信息同步服务代码存放目录
内存中保存token信息的结构,对应到数据库的hap_token_info_table表
- class HapTokenInfo final {
- public:
- ATokenAplEnum apl;
- char ver;
- int userID;
- std::string bundleName;
- int instIndex;
- std::string appID;
- std::string deviceID;
- AccessTokenID tokenID;
- AccessTokenAttr tokenAttr;
- };
appid = 应用包名+证书hash
存储tokenid和对应权限状态的关系类
基本类型,tokenid就是一个int型。
typedef unsigned int AccessTokenID;
tokenid主要是如下的四部分组成的
- typedef struct {
- unsigned int tokenUniqueID : 20;
- unsigned int res : 7;
- unsigned int type : 2;
- unsigned int version : 3;
- } AccessTokenIDInner;
主要存储应用的token信息
列名 | 类型 | 备注 |
token_id | integer | |
user_id | integer | |
bundle_name | text | |
inst_index | integer | |
app_id | text | |
device_id | text | |
apl | integer | |
token_version | integer | |
token_attr | integer |
primary key : token_id
native服务的token信息
列名 | 类型 | 备注 |
token_id | integer | |
process_name | text | |
token_version | integer | |
token_attr | integer | |
dcap | text | |
apl | integer |
primary key : token_id
权限定义表
列名 | 类型 | 备注 |
token_id | integer | |
permission_name | text | |
bundle_name | text | |
grant_mode | integer | |
available_level | integer | |
provision_enable | integer | |
distributed_scene_enable | integer | |
label | text | |
label_id | text | |
description | text | |
description_id | text |
primary key : token_id, permission_name
权限状态表
列名 | 类型 | |
token_id | integer | |
permission_name | text | |
device_id | text | |
is_general | integer | |
grant_state | integer | |
grant_flag | integer |
primary key : token_id, permission_name, device_id
整个启动过程,主要分为两部分。一部分是去数据库中加载动态的信息,还有一部分就是去系统定义的目录下加载静态的配置文件,静态配置文件主要是native service的token信息。
应用安装时生成
服务自己注册,静态配置文件中读取
远程应用访问本地设备时,根据远程应用的设备id,以及远程过来附带的tokenid,进行关系绑定,生成本地的tokenid。
相关本地token和权限的关系,是通过同步机制,从来源设备同步应用权限得到的。
分布式组件管理部件
分布式组件管理部件模块负责跨设备组件管理,提供访问和控制远程组件的能力,支持分布式场景下的应用协同。主要功能如下:
- 远程启动元能力:跨设备拉起远端设备上的指定元能力。
- 远程迁移元能力:将元能力跨设备迁移到远端设备。
- 远程绑定元能力:跨设备绑定远端设备上的指定元能力。
./distributedschedule/dmsfwk/services/dtbschedmgr/src/distributed_sched_permission.cpp:177: uint32_t dAccessToken = AccessToken::AccessTokenKit::AllocLocalTokenID(
任务调度过程中,会存在检查权限的场景,该服务会先创建远程tokenid,然后再会检查权限。
整个交互过程中,消息中会附带如下的信息
- struct CallerInfo {
- int32_t uid = -1;
- int32_t pid = -1;
- int32_t callerType = CALLER_TYPE_NONE;
- std::string sourceDeviceId;
- int32_t duid = -1;
- std::string callerAppId;
- std::vector<std::string> bundleNames;
- int32_t dmsVersion = -1;
- uint32_t accessToken = 0;
- };
远程启动应用的时候会去调用权限相关操作
- //远程启动应用
- int32_t DistributedSchedService::StartAbilityFromRemote(const OHOS::AAFwk::Want& want,
- const OHOS::AppExecFwk::AbilityInfo& abilityInfo, int32_t requestCode,
- const CallerInfo& callerInfo, const AccountInfo& accountInfo)
- {
- std::string localDeviceId;
- std::string deviceId = want.GetElement().GetDeviceID();
- if (!GetLocalDeviceId(localDeviceId) ||
- !CheckDeviceIdFromRemote(localDeviceId, deviceId, callerInfo.sourceDeviceId)) {
- HILOGE("check deviceId failed");
- return INVALID_REMOTE_PARAMETERS_ERR;
- }
- //检查权限
- DistributedSchedPermission& permissionInstance = DistributedSchedPermission::GetInstance();
- ErrCode err = permissionInstance.CheckDPermission(want, callerInfo, accountInfo, abilityInfo, deviceId);
- if (err != ERR_OK) {
- HILOGE("CheckDPermission denied!!");
- return err;
- }
- err = AAFwk::AbilityManagerClient::GetInstance()->Connect();
- if (err != ERR_OK) {
- HILOGE("connect ability server failed %{public}d", err);
- return err;
- }
- std::vector<int> ids;
- ErrCode ret = OsAccountManager::QueryActiveOsAccountIds(ids);
- if (ret != ERR_OK || ids.empty()) {
- return INVALID_PARAMETERS_ERR;
- }
- err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, requestCode, ids[0]);
- if (err != ERR_OK) {
- HILOGE("StartAbility failed %{public}d", err);
- }
- return err;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
-
- int32_t DistributedSchedService::StartAbilityByCallFromRemote(const OHOS::AAFwk::Want& want,
- const sptr<IRemoteObject>& connect, const CallerInfo& callerInfo, const AccountInfo& accountInfo)
- {
- HILOGD("[PerformanceTest] DistributedSchedService StartAbilityByCallFromRemote begin");
- if (connect == nullptr) {
- HILOGE("StartAbilityByCallFromRemote connect is null");
- return INVALID_REMOTE_PARAMETERS_ERR;
- }
- std::string localDeviceId;
- std::string destinationDeviceId = want.GetElement().GetDeviceID();
- if (!GetLocalDeviceId(localDeviceId) ||
- !CheckDeviceIdFromRemote(localDeviceId, destinationDeviceId, callerInfo.sourceDeviceId)) {
- HILOGE("StartAbilityByCallFromRemote check deviceId failed");
- return INVALID_REMOTE_PARAMETERS_ERR;
- }
-
- DistributedSchedPermission& permissionInstance = DistributedSchedPermission::GetInstance();
- int32_t result = permissionInstance.CheckGetCallerPermission(want, callerInfo, accountInfo, localDeviceId);
- if (result != ERR_OK) {
- HILOGE("StartAbilityByCallFromRemote CheckDPermission denied!!");
- return result;
- }
- sptr<IRemoteObject> callbackWrapper;
- {
- std::lock_guard<std::mutex> autoLock(calleeLock_);
- auto itConnect = calleeMap_.find(connect);
- if (itConnect != calleeMap_.end()) {
- callbackWrapper = itConnect->second.callbackWrapper;
- } else {
- callbackWrapper = new AbilityConnectionWrapperStub(connect, localDeviceId);
- }
- }
- int32_t errCode = DistributedSchedAdapter::GetInstance().StartAbilityByCall(want, callbackWrapper, this);
- HILOGD("[PerformanceTest] StartAbilityByCallFromRemote end");
- if (errCode == ERR_OK) {
- {
- std::lock_guard<std::mutex> autoLock(calleeLock_);
- ConnectInfo connectInfo {callerInfo, callbackWrapper, want.GetElement()};
- calleeMap_.emplace(connect, connectInfo);
- }
- connect->AddDeathRecipient(callerDeathRecipient_);
- }
- return errCode;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
-
- int32_t DistributedSchedService::ConnectAbilityFromRemote(const OHOS::AAFwk::Want& want,
- const AppExecFwk::AbilityInfo& abilityInfo, const sptr<IRemoteObject>& connect,
- const CallerInfo& callerInfo, const AccountInfo& accountInfo)
- {
- HILOGD("[PerformanceTest] DistributedSchedService ConnectAbilityFromRemote begin");
- if (connect == nullptr) {
- HILOGE("ConnectAbilityFromRemote connect is null");
- return INVALID_REMOTE_PARAMETERS_ERR;
- }
- HILOGD("ConnectAbilityFromRemote uid is %{public}d, pid is %{public}d, AccessTokenID is %{public}u",
- callerInfo.uid, callerInfo.pid, callerInfo.accessToken);
- std::string localDeviceId;
- std::string destinationDeviceId = want.GetElement().GetDeviceID();
- if (!GetLocalDeviceId(localDeviceId) ||
- !CheckDeviceIdFromRemote(localDeviceId, destinationDeviceId, callerInfo.sourceDeviceId)) {
- HILOGE("ConnectAbilityFromRemote check deviceId failed");
- return INVALID_REMOTE_PARAMETERS_ERR;
- }
-
- DistributedSchedPermission& permissionInstance = DistributedSchedPermission::GetInstance();
- int32_t result = permissionInstance.CheckDPermission(want, callerInfo, accountInfo, abilityInfo, localDeviceId);
- if (result != ERR_OK) {
- HILOGE("ConnectAbilityFromRemote CheckDPermission denied!!");
- return result;
- }
-
- HILOGD("ConnectAbilityFromRemote callerType is %{public}d", callerInfo.callerType);
- sptr<IRemoteObject> callbackWrapper = connect;
- std::map<sptr<IRemoteObject>, ConnectInfo>::iterator itConnect;
- if (callerInfo.callerType == CALLER_TYPE_HARMONY) {
- std::lock_guard<std::mutex> autoLock(connectLock_);
- itConnect = connectAbilityMap_.find(connect);
- if (itConnect != connectAbilityMap_.end()) {
- callbackWrapper = itConnect->second.callbackWrapper;
- } else {
- callbackWrapper = new AbilityConnectionWrapperStub(connect);
- }
- }
- int32_t errCode = DistributedSchedAdapter::GetInstance().ConnectAbility(want, callbackWrapper, this);
- HILOGD("[PerformanceTest] ConnectAbilityFromRemote end");
- if (errCode == ERR_OK) {
- std::lock_guard<std::mutex> autoLock(connectLock_);
- if (itConnect == connectAbilityMap_.end()) {
- ConnectInfo connectInfo {callerInfo, callbackWrapper};
- connectAbilityMap_.emplace(connect, connectInfo);
- }
- }
- return errCode;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- /**
- * @brief 检查权限
- *
- * @param tokenID
- * @param permissionName
- * @return int
- */
- int PermissionManager::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName)
- {
- ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x, permissionName: %{public}s", __func__,
- tokenID, permissionName.c_str());
- //检查权限名是否合法
- if (!PermissionValidator::IsPermissionNameValid(permissionName)) {
- ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
- return PERMISSION_DENIED;
- }
- std::shared_ptr<HapTokenInfoInner> tokenInfoPtr =
- AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenID);
- if (tokenInfoPtr == nullptr) {
- ACCESSTOKEN_LOG_ERROR(LABEL, "can not find tokenInfo!");
- return PERMISSION_DENIED;
- }
-
- //远程的应用,并且本地没有对应权限定义。直接拒绝
- if (!tokenInfoPtr->IsRemote() && !PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) {
- ACCESSTOKEN_LOG_ERROR(
- LABEL, "no definition for permission: %{public}s!", permissionName.c_str());
- return PERMISSION_DENIED;
- }
- std::shared_ptr<PermissionPolicySet> permPolicySet =
- AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID);
- if (permPolicySet == nullptr) {
- ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
- return PERMISSION_DENIED;
- }
-
- //根据数据库中加载的授权信息进行权限状态的检查。
- return permPolicySet->VerifyPermissStatus(permissionName);
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
目前看到的tokenid是在binder里面使用的,原本的binder传输的是uid,目前鸿蒙系统中新增了tokenid的传输,目前可以直接从binder里面获取。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。