陈晓 发表于 2025-3-30 16:37:14

简析OpenHarmony用户鉴权

用户凭证管理:
pin_auth(口令认证):模块支持用户口令的设置,删除和认证功能。与用户IAM子系统基础框架配合,也可以支持用户口令修改的功能;口令认证作为OpenHarmony最基础的用户身份认证执行器,按照协同认证定义的资源注册接口,将口令认证相关资源信息注册到协同认证框架,并根据协同认证框架的调度,完成口令的设置,删除和认证功能;face_auth(人脸认证):支持用户人脸的录入,删除和认证功能;人脸认证是OpenHarmony支持的一种生物认证执行器,按照协同认证定义的资源注册接口,将人脸认证相关资源信息注册到协同认证框架,并根据协同认证框架的调度,调用人脸认证HDI,完成人脸的录入,认证,删除等功能。user_auth_framework:主要包括三个模块,用户认证、凭据管理和执行器管理:
用户认证模块对外提供统一用户身份认证功能,并且开放生物特征认证API给三方应用调用。凭据管理模块提供系统内统一的用户凭据管理(增删改查)接口,向下通过执行器管理模块,调用系统内的执行器资源,完成用户凭据的生命周期管理和安全存储。执行器管理模块提供系统内执行器资源的统一管理和协同调度能力,当前支持口令执行器和人脸执行器的管理。

使用:

[*]接口
import osAccount from '@ohos.account.osAccount'

[*]凭证管理
//UserIdentityManager
/**
* Provides the abilities for managing user identity.
* @name UserIdentityManager
* @syscap SystemCapability.Account.OsAccount
* @since 8
*/
class UserIdentityManager {
   /**
 * Constructor to get the UserIdentityManager class instance.
 * @returns Returns the UserIdentityManager class instance.
 * @systemapi Hide this for inner system use.
 * @since 8
 */
   constructor();

   /**
 * Opens session.
 *
 * Start an IDM operation to obtain challenge value.
 * A challenge value of 0 indicates that opensession failed.
 * @permission ohos.permission.MANAGE_USER_IDM
 * @returns Returns a challenge value.
 * @throws {BusinessError} 201 - permission denied.
 * @throws {BusinessError} 401 - the parameter check failed.
 * @throws {BusinessError} 12300001 - system service exception.
 * @systemapi Hide this for inner system use.
 * @since 8
 */
   openSession(callback: AsyncCallback): void;
   openSession(): Promise;

   /**
 * Adds credential.
 *
 * Add user credential information, pass in credential addition method and credential information
 * (credential type, subclass, if adding user's non password credentials, pass in password authentication token),
 * and get the result / acquireinfo callback.
 * @permission ohos.permission.MANAGE_USER_IDM
 * @param credentialInfo Indicates the credential information.
 * @param callback Indicates the callback to get results and acquireInfo.
 * @throws {BusinessError} 201 - permission denied.
 * @throws {BusinessError} 401 - the parameter check failed.
 * @throws {BusinessError} 12300001 - system service exception.
 * @throws {BusinessError} 12300002 - invalid credentialInfo.
 * @systemapi Hide this for inner system use.
 * @since 8
 */
   addCredential(credentialInfo: CredentialInfo, callback: IIdmCallback): void;

   /**
 * Updates credential.
 * @permission ohos.permission.MANAGE_USER_IDM
 * @param credentialInfo Indicates the credential information.
 * @param callback Indicates the callback to get results and acquireInfo.
 * @throws {BusinessError} 201 - permission denied.
 * @throws {BusinessError} 401 - the parameter check failed.
 * @throws {BusinessError} 12300001 - system service exception.
 * @throws {BusinessError} 12300002 - invalid credentialInfo.
 * @systemapi Hide this for inner system use.
 * @since 8
 */
   updateCredential(credentialInfo: CredentialInfo, callback: IIdmCallback): void;

   /**
 * Closes session.
 *
 * End an IDM operation.  
 * @permission ohos.permission.MANAGE_USER_IDM
 * @systemapi Hide this for inner system use.
 * @since 8
 */
   closeSession(): void;

   /**
 * Cancels entry with a challenge value.
 * @permission ohos.permission.MANAGE_USER_IDM
 * @param challenge Indicates the challenge value.
 * @throws {BusinessError} 201 - permission denied.
 * @throws {BusinessError} 401 - the parameter check failed.
 * @throws {BusinessError} 12300001 - system service exception.
 * @throws {BusinessError} 12300002 - invalid challenge.
 * @systemapi Hide this for inner system use.
 * @since 8
 */
   cancel(challenge: Uint8Array): void;

   /**
 * Deletes the user with the authentication token.
 * @permission ohos.permission.MANAGE_USER_IDM
 * @param token Indicates the authentication token.
 * @param callback Indicates the callback to get the deletion result.
 * @throws {BusinessError} 201 - permission denied.
 * @throws {BusinessError} 401 - the parameter check failed.
 * @throws {BusinessError} 12300001 - system service exception.
 * @throws {BusinessError} 12300002 - invalid token.
 * @systemapi Hide this for inner system use.
 * @since 8
 */
   delUser(token: Uint8Array, callback: IIdmCallback): void;

   /**
 * Deletes the user credential information.
 * @permission ohos.permission.MANAGE_USER_IDM
 * @param credentialId Indicates the credential index.
 * @param token Indicates the authentication token.
 * @param callback Indicates the callback to get the deletion result.
 * @throws {BusinessError} 201 - permission denied.
 * @throws {BusinessError} 401 - the parameter check failed.
 * @throws {BusinessError} 12300001 - system service exception.
 * @throws {BusinessError} 12300002 - invalid credentialId or token.
 * @systemapi Hide this for inner system use.
 * @since 8
 */
   delCred(credentialId: Uint8Array, token: Uint8Array, callback: IIdmCallback): void;

   /**
 * Gets authentication information.
 * @permission ohos.permission.USE_USER_IDM
 * @param authType Indicates the authentication type.
 * @param callback Indicates the callback to get all registered credential information of
 * the specified type for the current user.
 * @throws {BusinessError} 201 - permission denied.
 * @throws {BusinessError} 401 - the parameter check failed.
 * @throws {BusinessError} 12300001 - system service exception.
 * @throws {BusinessError} 12300002 - invalid authType.
 * @throws {BusinessError} 12300015 - the authType is not supported on current device.
 * @throws {BusinessError} 12300016 - authentication timeout.
 * @throws {BusinessError} 12300017 - authentication service is busy.
 * @throws {BusinessError} 12300018 - authentication service is locked.
 * @throws {BusinessError} 12300019 - the credential does not exist.
 * @systemapi Hide this for inner system use.
 * @since 8
 */
   getAuthInfo(callback: AsyncCallback): void;
   getAuthInfo(authType: AuthType, callback: AsyncCallback): void;
   getAuthInfo(authType?: AuthType): Promise;
}
[*]用户管理
/**
    * Provides the abilities for user authentication.
    * @name UserAuth
    * @syscap SystemCapability.Account.OsAccount
    * @since 8
    */
   class UserAuth {
       /**
        * Constructor to get the UserAuth class instance.
        * @returns Returns the UserAuth class instance.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       constructor();

       /**
        * Gets version information.
        * @returns Returns the version information.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       getVersion(): number;

       /**
        * Checks whether the authentication capability is available.
        * @permission ohos.permission.ACCESS_USER_AUTH_INTERNAL
        * @param authType Indicates the credential type for authentication.
        * @param authTrustLevel Indicates the trust level of authentication result.
        * @returns Returns a status result.
        * @throws {BusinessError} 201 - permission denied.
        * @throws {BusinessError} 401 - the parameter check failed.
        * @throws {BusinessError} 12300001 - system service exception.
        * @throws {BusinessError} 12300002 - invalid authType or authTrustLevel.
        * @throws {BusinessError} 12300014 - the authTrustLevel is not supported on current device
        * @throws {BusinessError} 12300015 - the authType is not supported on current device.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       getAvailableStatus(authType: AuthType, authTrustLevel: AuthTrustLevel): number;

       /**
        * Gets the property based on the specified request information.
        * @permission ohos.permission.ACCESS_USER_AUTH_INTERNAL
        * @param request Indicates the request information, including authentication type, and property type list.
        * @returns Returns an executor property.
        * @throws {BusinessError} 201 - permission denied.
        * @throws {BusinessError} 401 - the parameter check failed.
        * @throws {BusinessError} 12300001 - system service exception.
        * @throws {BusinessError} 12300002 - invalid request.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       getProperty(request: GetPropertyRequest, callback: AsyncCallback): void;
       getProperty(request: GetPropertyRequest): Promise;

       /**
        * Sets property that can be used to initialize algorithms.
        * @permission ohos.permission.ACCESS_USER_AUTH_INTERNAL
        * @param request Indicates the request information, including authentication type and the key-value to be set.
        * @returns Returns a number value indicating whether the property setting was successful.
        * @throws {BusinessError} 201 - permission denied.
        * @throws {BusinessError} 401 - the parameter check failed.
        * @throws {BusinessError} 12300001 - system service exception.
        * @throws {BusinessError} 12300002 - invalid request.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       setProperty(request: SetPropertyRequest, callback: AsyncCallback): void;
       setProperty(request: SetPropertyRequest): Promise;

       /**
        * Executes authentication.
        * @permission ohos.permission.ACCESS_USER_AUTH_INTERNAL
        * @param challenge Indicates the challenge value.
        * @param authType Indicates the authentication type.
        * @param authTrustLevel Indicates the trust level of authentication result.
        * @param callback Indicates the callback to get result and acquireInfo.
        * @returns Returns a context ID for cancellation.
        * @throws {BusinessError} 201 - permission denied.
        * @throws {BusinessError} 401 - the parameter check failed.
        * @throws {BusinessError} 12300001 - system service exception.
        * @throws {BusinessError} 12300002 - invalid challenge, authType or authTrustLevel.
        * @throws {BusinessError} 12300014 - the authTrustLevel is not supported on current device
        * @throws {BusinessError} 12300015 - the authType is not supported on current device.
        * @throws {BusinessError} 12300016 - authentication timeout.
        * @throws {BusinessError} 12300017 - authentication service is busy.
        * @throws {BusinessError} 12300018 - authentication service is locked.
        * @throws {BusinessError} 12300019 - the credential does not exist.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       auth(challenge: Uint8Array, authType: AuthType, authTrustLevel: AuthTrustLevel, callback: IUserAuthCallback): Uint8Array;

       /**
        * Executes user authentication.
        * @permission ohos.permission.ACCESS_USER_AUTH_INTERNAL
        * @param userId Indicates the user identification.
        * @param challenge Indicates the challenge value.
        * @param authType Indicates the authentication type.
        * @param authTrustLevel Indicates the trust level of authentication result.
        * @param callback Indicates the callback to get result and acquireInfo.
        * @returns Returns a context ID for cancellation.
        * @throws {BusinessError} 201 - permission denied.
        * @throws {BusinessError} 401 - the parameter check failed.
        * @throws {BusinessError} 12300001 - system service exception.
        * @throws {BusinessError} 12300002 - invalid userId, challenge, authType or authTrustLevel.
        * @throws {BusinessError} 12300003 - the account indicated by userId dose not exist.
        * @throws {BusinessError} 12300014 - the authTrustLevel is not supported on current device
        * @throws {BusinessError} 12300015 - the authType is not supported on current device.
        * @throws {BusinessError} 12300016 - authentication timeout.
        * @throws {BusinessError} 12300017 - authentication service is busy.
        * @throws {BusinessError} 12300018 - authentication service is locked.
        * @throws {BusinessError} 12300019 - the credential does not exist.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       authUser(userId: number, challenge: Uint8Array, authType: AuthType, authTrustLevel: AuthTrustLevel, callback: IUserAuthCallback): Uint8Array;

       /**
        * Cancels authentication with context ID.
        * @permission ohos.permission.ACCESS_USER_AUTH_INTERNAL
        * @param contextID Indicates the authentication context ID.
        * @throws {BusinessError} 201 - permission denied.
        * @throws {BusinessError} 401 - the parameter check failed.
        * @throws {BusinessError} 12300001 - system service exception.
        * @throws {BusinessError} 12300002 - invalid contexId.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       cancelAuth(contextID: Uint8Array): void;
 }
[*]口令管理
/**
    * Provides the abilities for Pin code authentication.
    * @name PINAuth
    * @syscap SystemCapability.Account.OsAccount
    * @since 8
    */
class PINAuth {
    /**
    * Constructor to get the PINAuth class instance.
    * @returns Returns the PINAuth class instance.
    * @systemapi Hide this for inner system use.
    * @since 8
    */
   constructor();

   /**
    * Register inputer.
 * @permission ohos.permission.ACCESS_PIN_AUTH
 * @param inputer Indicates the password input box callback
 * @throws {BusinessError} 201 - permission denied.
 * @throws {BusinessError} 401 - the parameter check failed.
 * @throws {BusinessError} 12300001 - system service exception.
 * @throws {BusinessError} 12300007 - PIN inputer has been registered.
 * @systemapi Hide this for inner system use.
 * @since 8
 */
   registerInputer(inputer: IInputer): void;

   /**
 * Unregister inputer.
 * @permission ohos.permission.ACCESS_PIN_AUTH
 * @systemapi Hide this for inner system use.
 * @since 8
 */
   unregisterInputer(): void;
}
[*]回调:IInputData,Inputer回调时带的参数,用来输入口令
/**
    * Password data callback.
    *
    * @name IInputData
    * @syscap SystemCapability.Account.OsAccount
    * @systemapi Hide this for inner system use.
    * @since 8
    */
   interface IInputData {
       /**
        * Notifies to set data.
        * @param pinSubType Indicates the credential subtype for authentication.
        * @param data Indicates the data to set.
        * @throws {BusinessError} 401 - the parameter check failed.
        * @throws {BusinessError} 12300002 - invalid pinSubType.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       onSetData: (pinSubType: AuthSubType, data: Uint8Array) => void;
 }
[*]回调:IInputer,regitsterInputer是传入的回调,在需要输密码时被调用
/**
    * Password input box callback.
    * @name IInputer
    * @syscap SystemCapability.Account.OsAccount
    * @systemapi Hide this for inner system use.
    * @since 8
    */
   interface IInputer {
       /**
        * Notifies to get data.
        * @param pinSubType Indicates the credential subtype for authentication.
        * @param callback Indicates the password data callback.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       onGetData: (pinSubType: AuthSubType, callback: IInputData) => void;
 }
[*]回调:IUserAuthCallback,auth,authUser的回调,用来接收auth的结果
/**
    * User authentication callback.
    * @name IUserAuthCallback
    * @syscap SystemCapability.Account.OsAccount
    * @systemapi Hide this for inner system use.
    * @since 8
    */
   interface IUserAuthCallback {
       /**
        * The authentication result code is returned through the callback.
        * @param result Indicates the authentication result code.
        * @param extraInfo Indicates the specific information for different situation.
        * If the authentication is passed, the authentication token is returned in extrainfo,
        * If the authentication fails, the remaining authentication times are returned in extrainfo,
        * If the authentication executor is locked, the freezing time is returned in extrainfo.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       onResult: (result: number, extraInfo: AuthResult) => void;

       /**
        * During an authentication, the TipsCode is returned through the callback.
        * @param module Indicates the executor type for authentication.
        * @param acquire Indicates the tip code for different authentication executor.
        * @param extraInfo reserved parameter.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       onAcquireInfo?: (module: number, acquire: number, extraInfo: any) => void;
 }
[*]回调:IIdmCallback,addCredential,updateCredential,delUser,delCred的回调,用来收听onResult是否成功
/**
    * Identity manager callback.
    * @name IIdmCallback
    * @syscap SystemCapability.Account.OsAccount
    * @systemapi Hide this for inner system use.
    * @since 8
    */
   interface IIdmCallback {
       /**
        * The authentication result code is returned through the callback.
        * @param result Indicates the authentication result code.
        * @param extraInfo pass the specific information for different situation.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       onResult: (result: number, extraInfo: RequestResult) => void;

       /**
        * During an authentication, the TipsCode is returned through the callback.
        * @param module Indicates the executor type for authentication.
        * @param acquire Indicates the tip code for different authentication executor.
        * @param extraInfo reserved parameter.
        * @systemapi Hide this for inner system use.
        * @since 8
        */
       onAcquireInfo?: (module: number, acquire: number, extraInfo: any) => void;
 }
流程:
havePasswordnoPassworduserIdentityManager::openSessionpinAuth::registerInputeruserIdentityManager::getAuthInfouserAuth::getPropertyuserIdentityManager::addCredential

[*]构建对象
//三个对象
this.userIdentityManager = new osAccount.UserIdentityManager();
this.pinAuth = new osAccount.PINAuth();
this.userAuth = new osAccount.UserAuth();
[*]opensession
/**
  * Open Session
  * A challenge value of 0 indicates that opensession failed
  *
  * @returns challenge value
  */
 openSession(callback: (challenge: string) => void): void {
   LogUtil.debug(`${this.TAG}openSession in.`);
   try {
     this.userIdentityManager.openSession()
                             .then((data) =>{
                               callback(this.u8AToStr(data));
                               LogUtil.info(`${this.TAG} openSession success`);
                             })
                             .catch((err) => {
                               LogUtil.error(`${this.TAG} openSession failed` + JSON.stringify(err));
                             })
   } catch {
     LogUtil.error(`${this.TAG}openSession failed`);
     callback('0');
   }
   LogUtil.debug(`${this.TAG}openSession out.`);
 }
[*]注册inputer
/**
  * Register Inputer
  */
 registerInputer(): boolean {
   LogUtil.debug(`${this.TAG}registerInputer in.`);
   let result = false;
   try {
     result = this.pinAuth.registerInputer({
       onGetData: (authSubType, inputData) => {
         let u8aPwd = this.encodeToU8A(this.password);
         LogUtil.info(`${this.TAG} before set data, type: ${this.pinSubType}.`);
         inputData.onSetData(this.pinSubType, u8aPwd);
     }
   });
     if(!result){
       this.unregisterInputer();
       result = this.pinAuth.registerInputer({
         onGetData: (authSubType, inputData) => {
           let u8aPwd = this.encodeToU8A(this.password);
           inputData.onSetData(this.pinSubType, u8aPwd);
       }
     });
   }
 } catch {
     LogUtil.error(`${this.TAG}registerInputer failed`);
 }
   LogUtil.info(`${this.TAG}registerInputer out.`);
   return result;
}
[*]createPassword
/**
  * Call api to create password
  */
 createPassword() {
   PasswordModel.addPinCredential(this.passwordType, this.password, (result) => {
     if (result === ResultCode.SUCCESS) {
       LogUtil.info(`${this.TAG}create password success`);
       this.goBackCorrect();
   } else {
       LogUtil.info(`${this.TAG}create password failed`);
       //TODO show api message to view
       this.checkMessage = 'create failed.';
   }
 });
}
[*]getAuthInfo
/**
  * Get AuthInfo
  *
  * @param authType Credential type.
  * @returns Returns all registered credential information of this type for the current user
  */
 getPinAuthInfo(callback: (data: Array) => void): void {
   LogUtil.debug(`${this.TAG}getPinAuthInfo in.`);
   try {
     this.userIdentityManager.getAuthInfo(AuthType.PIN)
                             .then((data) => {
                               LogUtil.info(`${this.TAG} get pin auth info data.`);
                               let arrCredInfo = [];
                               try {
                                 for(let i = 0; i < data.length; i++) {
                                   let credInfo = {
                                     'authType': data.authType,
                                     'authSubType': data.authSubType
                                   };

                                   if (credInfo.authType == AuthType.PIN) {
                                     this.pinSubType = credInfo.authSubType;
                                   }
                                   arrCredInfo.push(credInfo);
                                 }
                               } catch(e) {
                                 LogUtil.info('faceDemo pin.getAuthInfo error = ' + e);
                               }
                               callback(arrCredInfo);
                               LogUtil.info(`${this.TAG} getAuthInfo success.`);
                             })
                             .catch((err) => {
                               LogUtil.error(`${this.TAG} getAuthInfo failed.` + JSON.stringify(err));
                             })
   } catch (e) {
     LogUtil.error(`${this.TAG}getPinAuthInfo failed:` + e);
   }
   LogUtil.debug(`${this.TAG}getPinAuthInfo out.`);
 }
[*]autPin
/**
  * Auth
  *
  * @param challenge pass in challenge value. challenge是从openSession的回调得到
  * @param password password
  * @param onResult Return results through callback.
  */
 authPin(challenge: string, password: string, onResult: (result: number, extraInfo: {
   token?: string;
   remainTimes?: number;
   freezingTime?: number;
}) => void): void {
   LogUtil.debug(`${this.TAG}authPin in.`);
   this.password = password;
   try {
     LogUtil.info(`${this.TAG} before userAuth auth pin`);
     this.userAuth.auth(this.strToU8A(challenge), AuthType.PIN, AuthTrustLevel.ATL4, {
       onResult: (result, extraInfo) => {
         try{
           if (result === ResultCode.SUCCESS) {
             LogUtil.debug(`${this.TAG}userAuth.auth onResult: result = success`);
           } else {
             LogUtil.debug(`${this.TAG}userAuth.auth failed onResult: result =  ${result}`);
           }
           let info = {
             'token':this.u8AToStr(extraInfo?.token),
             'remainTimes': extraInfo.remainTimes,
             'freezingTime': extraInfo.freezingTime
           }
           onResult(result, info)
         }
         catch(e) {
           LogUtil.debug(`${this.TAG}userAuth.auth onResult error = ${JSON.stringify(e)}`);
         }
       },

       onAcquireInfo: (acquireModule, acquire, extraInfo) => {
         try{
           LogUtil.debug(this.TAG + 'faceDemo pin.auth onAcquireInfo acquireModule = ' + acquireModule);
           LogUtil.debug(this.TAG + 'faceDemo pin.auth onAcquireInfo acquire = ' + acquire);
         }
         catch(e) {
           LogUtil.error(this.TAG + 'faceDemo pin.auth onAcquireInfo error = ' + e);
         }
       }
     })

   } catch (e) {
     LogUtil.error(`${this.TAG}AuthPin failed:` + e);
   }
   LogUtil.debug(`${this.TAG}authPin out.`);
 }

概述

小结

用户鉴权(包括屏保)是以accountmgr服务为入口为应用层提供功能,以useridm为实现,完成具体的口令管理和人脸管理(人脸管理目前还有欠缺)用户鉴权是系统级服务,要求ohos.permission.MANAGE_USER_IDM, ohos.permission.USE_USER_IDM,ohos.permission.MANAGE_LOCAL_ACCOUNTS,ohos.permission.ACCESS_USER_AUTH_INTERNAL,ohos.permission.ACCESS_PIN_AUTH权限和selinux权限(富设备支持)

小川8433651 发表于 2025-3-30 16:37:34

我在签名中配置了
"apl":"system_core",
"app-feature":"hos_system_app"
目前遇到了这样的问题(不是系统hap,没有selinux权限,没打包设置)
请问如何才能让应用拥有selinux权限
页: [1]
查看完整版本: 简析OpenHarmony用户鉴权