1# User Authentication 2 3## Overview 4 5### Function 6 7User authentication is indispensable in identity authentication scenarios, such as device unlocking, payment, and app logins. The user authentication framework (User_auth) manages the mappings between user identities and authentication credential templates in a unified manner. It schedules executors implemented by basic authentication services (including PIN authentication and facial recognition) to register user authentication credentials, delete credentials, obtain related information, and complete authentication. The figure below shows the architecture of user authentication. 8 9The User_auth driver is developed based on the Hardware Driver Foundation (HDF). It shields hardware differences and provides stable user authentication capabilities for apps and account management system ability (SA). It supports user credential management, authentication information enrollment, authentication scheme generation, and executor information management. 10 11**Figure 1** User authentication architecture 12 13![image](figures/user_auth_architecture.png "User authentication architecture") 14 15### Basic Concepts 16The identity authentication consists of the User_auth framework and basic authentication services (including PIN authentication and facial recognition). It supports basic functions such as setting and deleting user credentials and performing authentication. 17 18- Authentication credential information 19 20 An authentication credential template is generated when a user sets a password or enrolls facial information. The credential information consists of the user identity information and credential template information. The authentication is successful when the credential data generated matches the credential template information. 21 22- Authentication credential template 23 24 The authentication credential template is generated and stored by the authentication service when a user sets the authentication credential. The template information needs to be compared with the authentication data generated during authentication to complete identity authentication. Each template has an ID to index a set of template information files. 25 26- Executor 27 28 The executor collects, processes, stores, and compares data for authentication. Each authentication service provides the executor capabilities, which are scheduled by User_auth to implement basic capabilities. 29 30- Executor role 31 32 - Executor: independently completes the entire process of credential registration and identity authentication. The executor can collect, process, store, and compare data to complete the authentication. 33 34 - Collector: only collects data during user authentication. It needs to work with the authenticator to complete user authentication. 35 36 - Authenticator: processes data, obtains the stored credential template, and compares it with the authentication information generated. 37 38- Executor type 39 40 The authentication algorithm varies depending on the authentication mode and device used. Different executor types are defined based on the supported algorithm type or the device in use. 41 42- Executor security level 43 44 Security level required for the execution environment of an executor. 45 46- User_auth public key & executor public key 47 48 To ensure user data security and authentication result accuracy, measures must be taken to protect the integrity of the key information exchanged between User_auth and basic authentication services. Public keys must be exchanged when the executor provided by a basic authentication service interworks with User_auth. 49 50 - The executor uses the User_auth public key to verify scheduling instructions. For example, if a face image template is locked, the related facial authentication capability cannot be used. The instruction for unlocking the face image template must be verified before being executed. 51 52 - User_auth uses the executor public key to verify the authentication result accuracy and the integrity of the information exchanged with the executor. 53 54 55- Authentication result trust level 56 57 The trust level of the authentication result varies, depending on the authentication mode and the security level of the authentication execution environment. 58 59- Authentication scheme 60 61 An authentication scheme contains information about the authentication mode, trust level of the authentication result, executor, and credential. 62 63- Scheduling information 64 65 Scheduling information includes the executor information and credential template information required by the executor to process requests. User_auth schedules the executor to implement basic authentication capabilities. 66 67- SA 68 69 SAs are loaded by the System Ability Manager to provide basic system capabilities for OpenHarmony devices. 70 71- Kit 72 73 The kit provides basic APIs for third-party applications. 74 75- Inner API 76 77 Inner API is an API provided by OpenHarmony for system applications. 78 79### Working Principles 80 81The User_auth driver shields the differences of security devices and environments. It provides unified interfaces for the User_auth service to implement management of executors and credentials as well as authentication scheme generation. 82You can develop drivers to call Hardware Device Interface (HDI) APIs based on the HDF and the chip you use. 83 84**Figure 2** User_auth service and User_auth driver APIs 85 86![image](figures/user_auth_service_and_driver_api.png "interaction between the user_auth service and driver") 87 88### Constraints 89 90The User_auth driver must be implemented in a Trusted Execution Environment (TEE) to ensure secure storage of user credentials and trustworthiness of user authentication results. 91 92## Development Guidelines 93 94### When to Use 95 96The User_auth driver provides stable user credential management, authentication session management, and executor information management for the User_auth service to ensure successful PIN authentication and biometric recognition on devices. 97 98### Available APIs 99 100**Table 1** Available APIs 101 102| API | Description | 103| ------------------------------------------------------------ | ------------------------------------------------------------ | 104| Init() | Initializes cached information. | 105| AddExecutor(const ExecutorRegisterInfo& info, uint64_t& index, std::vector<uint8_t>& publicKey,<br> std::vector<uint64_t>& templateIds) | Adds an executor to obtain the authentication capability. | 106| DeleteExecutor(uint64_t index) | Deletes an executor. | 107| OpenSession(int32_t userId, std::vector<uint8_t>& challenge) | Opens a session for authentication credential management. | 108| CloseSession(int32_t userId) | Closes a session for authentication credential management. | 109| BeginEnrollment(int32_t userId, const std::vector<uint8_t>& authToken, const EnrollParam& param,<br> ScheduleInfo& info) | Enrolls the user authentication credential. If a user has enrolled a PIN, the old PIN will be overwritten.| 110| UpdateEnrollmentResult(int32_t userId, const std::vector<uint8_t>& scheduleResult, uint64_t& credentialId,<br> CredentialInfo& oldInfo) | Updates the data to complete this enrollment. | 111| CancelEnrollment(int32_t userId) | Cancels an enrollment operation. | 112| DeleteCredential(int32_t userId, uint64_t credentialId, const std::vector<uint8_t>& authToken,<br> CredentialInfo& info) | Deletes credential information based on the specified **credentialId**. | 113| DeleteUser(int32_t userId, const std::vector<uint8_t>& authToken,<br> std::vector<CredentialInfo>& deletedInfos) | Deletes a user PIN from User_auth. | 114| EnforceDeleteUser(int32_t userId, std::vector<CredentialInfo>& deletedInfos) | Forcibly deletes a user. This API will be called when a user is deleted from the system. | 115| GetCredential(int32_t userId, AuthType authType, std::vector<CredentialInfo>& infos) | Obtains user credential information by authentication type. | 116| GetSecureInfo(int32_t userId, uint64_t& secureUid, std::vector<EnrolledInfo>& infos) | Obtains the secure user ID and the enrolled tag ID of each authentication type. | 117| BeginAuthentication(uint64_t contextId, const AuthSolution& param,<br> std::vector<ScheduleInfo>& scheduleInfos) | Starts an authentication to generate the authentication scheme and scheduling information. | 118| UpdateAuthenticationResult(uint64_t contextId, const std::vector<uint8_t>& scheduleResult,<br> AuthResultInfo& info) | Updates the authentication result to evaluate the authentication scheme. | 119| CancelAuthentication(uint64_t contextId) | Cancels an authentication. | 120| BeginIdentification(uint64_t contextId, AuthType authType, const std::vector<int8_t>& challenge,<br> uint32_t executorId, ScheduleInfo& scheduleInfo) | Starts an identification to generate the identification scheme and scheduling information. | 121| UpdateIdentificationResult(uint64_t contextId, const std::vector<uint8_t>& scheduleResult,<br> IdentifyResultInfo& info) | Updates the identification result to evaluate the identification scheme. | 122| CancelIdentification(uint64_t contextId) | Cancels an identification. | 123| GetAuthTrustLevel(int32_t userId, AuthType authType, uint32_t& authTrustLevel) | Obtains the authentication trust level of the specified authentication type. | 124| GetValidSolution(int32_t userId, const std::vector<AuthType>& authTypes, uint32_t authTrustLevel,<br> std::vector<AuthType>& validTypes) | Obtains the valid authentication scheme based on the authentication trust level for a user. | 125 126### How to Develop 127 128The following uses the Hi3516D V300 development board as an example to demonstrate how to develop the User_auth driver. <br/>The directory structure is as follows: 129 130```undefined 131// drivers/peripheral/user_auth 132├── BUILD.gn # Build script 133├── bundle.json # Module description file 134└── hdi_service # User_auth driver implementation 135 ├── BUILD.gn # Build script 136 ├── module # Implementation of functionalities 137 └── service 138 ├── user_auth_interface_driver.cpp # User_auth driver entry 139 └── user_auth_interface_service.cpp # Implementation of the APIs for obtaining the executor list 140``` 141 142The development procedure is as follows: 143 1441. Develop the User_auth driver based on the HDF. The **Bind()**, **Init()**, **Release()**, and **Dispatch()** functions are used. For details about the code, see [user_auth_interface_driver.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/user_auth/hdi_service/service/user_auth_interface_driver.cpp). 145 146 ```c++ 147 // Create an IRemoteObject object by using the custom HdfUserAuthInterfaceHost object, which consists of the IoService object and HDI service. 148 struct HdfUserAuthInterfaceHost { 149 struct IDeviceIoService ioService; 150 OHOS::sptr<OHOS::IRemoteObject> stub; 151 }; 152 153 // Enable the IPC service to call the response API. 154 static int32_t UserAuthInterfaceDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, 155 struct HdfSBuf *reply) 156 { 157 auto *hdfUserAuthInterfaceHost = CONTAINER_OF(client->device->service, struct HdfUserAuthInterfaceHost, ioService); 158 159 OHOS::MessageParcel *dataParcel = nullptr; 160 OHOS::MessageParcel *replyParcel = nullptr; 161 OHOS::MessageOption option; 162 163 if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) { 164 HDF_LOGE("%{public}s:invalid data sbuf object to dispatch", __func__); 165 return HDF_ERR_INVALID_PARAM; 166 } 167 if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) { 168 HDF_LOGE("%{public}s:invalid reply sbuf object to dispatch", __func__); 169 return HDF_ERR_INVALID_PARAM; 170 } 171 172 return hdfUserAuthInterfaceHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option); 173 } 174 175 // Initialize the HdfUserAuthInterfaceDriver object. 176 int HdfUserAuthInterfaceDriverInit(struct HdfDeviceObject *deviceObject) 177 { 178 HDF_LOGI("HdfUserAuthInterfaceDriverInit enter"); 179 OHOS::UserIAM::Common::Init(); 180 return HDF_SUCCESS; 181 } 182 183 // Bind the service provided by the User_auth driver to the HDF. 184 int HdfUserAuthInterfaceDriverBind(struct HdfDeviceObject *deviceObject) 185 { 186 HDF_LOGI("HdfUserAuthInterfaceDriverBind enter"); 187 188 auto *hdfUserAuthInterfaceHost = new (std::nothrow) HdfUserAuthInterfaceHost; 189 if (hdfUserAuthInterfaceHost == nullptr) { 190 HDF_LOGE("%{public}s: Failed to create HdfUserAuthInterfaceHost object", __func__); 191 return HDF_FAILURE; 192 } 193 194 hdfUserAuthInterfaceHost->ioService.Dispatch = UserAuthInterfaceDriverDispatch; 195 hdfUserAuthInterfaceHost->ioService.Open = NULL; 196 hdfUserAuthInterfaceHost->ioService.Release = NULL; 197 198 auto serviceImpl = IUserAuthInterface::Get(true); 199 if (serviceImpl == nullptr) { 200 HDF_LOGE("%{public}s: Failed to obtain service", __func__); 201 return HDF_FAILURE; 202 } 203 204 hdfUserAuthInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl, 205 IUserAuthInterface::GetDescriptor()); 206 if (hdfUserAuthInterfaceHost->stub == nullptr) { 207 HDF_LOGE("%{public}s: failed to get stub object", __func__); 208 return HDF_FAILURE; 209 } 210 211 deviceObject->service = &hdfUserAuthInterfaceHost->ioService; 212 return HDF_SUCCESS; 213 } 214 215 // Release resources of the User_auth driver. 216 void HdfUserAuthInterfaceDriverRelease(struct HdfDeviceObject *deviceObject){ 217 HDF_LOGI("HdfUserAuthInterfaceDriverRelease enter"); 218 auto *hdfUserAuthInterfaceHost = CONTAINER_OF(deviceObject->service, struct HdfUserAuthInterfaceHost, ioService); 219 delete hdfUserAuthInterfaceHost; 220 } 221 222 // Register the User_auth driver entry data structure object. 223 struct HdfDriverEntry g_userAuthInterfaceDriverEntry = { 224 .moduleVersion = 1, 225 .moduleName = "user_auth_device_driver", 226 .Bind = HdfUserAuthInterfaceDriverBind, 227 .Init = HdfUserAuthInterfaceDriverInit, 228 .Release = HdfUserAuthInterfaceDriverRelease, 229 }; 230 231 // Call HDF_INIT to register the driver entry with the HDF. When loading the driver, the HDF calls the Bind() function and then the Init() function. If the Init() function fails to be called, the HDF will call Release() to release driver resources and exit the driver model. 232 #ifndef __cplusplus 233 extern "C" { 234 #endif 235 HDF_INIT(g_userAuthInterfaceDriverEntry); 236 #ifndef __cplusplus 237 } 238 #endif 239 ``` 240 2412. Register the executor. For details about the code, see [user_auth_interface_service.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/user_auth/hdi_service/service/user_auth_interface_service.cpp). 242 243 ```c++ 244 // Add an executor. 245 int32_t UserAuthInterfaceService::AddExecutor(const ExecutorRegisterInfo& info, uint64_t& index, 246 std::vector<uint8_t>& publicKey, std::vector<uint64_t>& templateIds) 247 { 248 GlobalLock(); 249 ExecutorInfoHal executorInfoHal; 250 CopyExecutorInfo(info, executorInfoHal); 251 int32_t ret = RegisterExecutor(&executorInfoHal, &index); 252 GlobalUnLock(); 253 return ret; 254 } 255 256 // Delete the executor. 257 int32_t UserAuthInterfaceService::DeleteExecutor(uint64_t index) 258 { 259 return UnRegisterExecutor(index); 260 } 261 ``` 262 2633. Enroll user authentication data. For details about the code, see [user_auth_interface_service.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/user_auth/hdi_service/service/user_auth_interface_service.cpp). 264 265 ```c++ 266 // Open a session for authentication credential management. 267 int32_t UserAuthInterfaceService::OpenSession(int32_t userId, std::vector<uint8_t>& challenge) 268 { 269 GlobalLock(); 270 uint64_t challengeU64 = 0; 271 int32_t ret = OpenEditSession(userId, &challengeU64); 272 challenge.resize(sizeof(uint64_t)); 273 if (memcpy_s(&challenge[0], challenge.size(), &challengeU64, sizeof(uint64_t)) != EOK) { 274 IAM_LOGE("Failed to copy challengeU64"); 275 return RESULT_BAD_COPY; 276 } 277 GlobalUnLock(); 278 return ret; 279 } 280 281 // Close the session for authentication credential management. 282 int32_t UserAuthInterfaceService::CloseSession(int32_t userId) 283 { 284 GlobalLock(); 285 int32_t ret = CloseEditSession(); 286 GlobalUnLock(); 287 return ret; 288 } 289 290 // Start an authentication to generate enrollment and scheduling information. 291 int32_t UserAuthInterfaceService::BeginEnrollment(int32_t userId, const std::vector<uint8_t>& authToken, 292 const EnrollParam& param, ScheduleInfo& info) 293 { 294 IAM_LOGI("start"); 295 GlobalLock(); 296 if (authToken.size() != sizeof(UserAuthTokenHal) && param.authType != PIN) { 297 IAM_LOGE("authToken len is invalid"); 298 GlobalUnLock(); 299 return RESULT_BAD_PARAM; 300 } 301 PermissionCheckParam checkParam; 302 if (authToken.size() == sizeof(UserAuthTokenHal) && 303 memcpy_s(checkParam.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) { 304 GlobalUnLock(); 305 return RESULT_BAD_COPY; 306 } 307 checkParam.authType = param.authType; 308 checkParam.userId = userId; 309 checkParam.authSubType = (uint64_t)param.executorType; 310 CoAuthSchedule scheduleInfo; 311 int32_t ret = CheckEnrollPermission(checkParam, &scheduleInfo.scheduleId); 312 if (ret != RESULT_SUCCESS) { 313 IAM_LOGE("Failed to check permission"); 314 GlobalUnLock(); 315 return ret; 316 } 317 ret = GetCoAuthSchedule(&scheduleInfo); 318 if (ret != RESULT_SUCCESS) { 319 IAM_LOGE("Failed to get schedule info"); 320 GlobalUnLock(); 321 return ret; 322 } 323 if (!CopyScheduleInfo(&scheduleInfo, &info)) { 324 IAM_LOGE("Failed to copy schedule info"); 325 ret = RESULT_BAD_COPY; 326 } 327 GlobalUnLock(); 328 return ret; 329 } 330 331 // Cancel the enrollment operation. 332 int32_t UserAuthInterfaceService::CancelEnrollment(int32_t userId) 333 { 334 IAM_LOGI("start"); 335 BreakOffCoauthSchedule(userId); 336 return RESULT_SUCCESS; 337 } 338 339 // Update the enrolled credential information. 340 int32_t UserAuthInterfaceService::UpdateEnrollmentResult(int32_t userId, const std::vector<uint8_t>& scheduleResult, 341 uint64_t& credentialId, CredentialInfo& oldInfo) 342 { 343 IAM_LOGI("start"); 344 GlobalLock(); 345 if (scheduleResult.size() == 0) { 346 IAM_LOGE("enrollToken is invalid"); 347 GlobalUnLock(); 348 return RESULT_BAD_PARAM; 349 } 350 Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size()); 351 if (scheduleResultBuffer == nullptr) { 352 IAM_LOGE("scheduleTokenBuffer is null"); 353 GlobalUnLock(); 354 return RESULT_NO_MEMORY; 355 } 356 bool isUpdate; 357 int32_t ret = GetIsUpdate(&isUpdate); 358 if (ret != RESULT_SUCCESS) { 359 IAM_LOGE("Failed to get isUpdate"); 360 return ret; 361 } 362 if (isUpdate) { 363 CredentialInfoHal oldCredentialHal; 364 ret = UpdateCredentialFunc(scheduleResultBuffer, &credentialId, &oldCredentialHal); 365 oldInfo.authType = static_cast<AuthType>(oldCredentialHal.authType); 366 oldInfo.credentialId = oldCredentialHal.credentialId; 367 oldInfo.templateId = oldCredentialHal.templateId; 368 oldInfo.executorType = static_cast<uint32_t>(oldCredentialHal.authSubType); 369 oldInfo.executorId = 0; 370 oldInfo.index = 0; 371 } else { 372 ret = AddCredentialFunc(scheduleResultBuffer, &credentialId); 373 } 374 DestoryBuffer(scheduleResultBuffer); 375 GlobalUnLock(); 376 return ret; 377 } 378 ``` 379 3804. Perform the authentication. For details about the code, see [user_auth_interface_service.cpp](https://gitee.com/openharmony/drivers_peripheral/blob/master/user_auth/hdi_service/service/user_auth_interface_service.cpp). 381 382 ```c++ 383 // Create an HDI service object. 384 extern "C" IUserAuthInterface *UserAuthInterfaceImplGetInstance(void) 385 { 386 auto userAuthInterfaceService = new (std::nothrow) UserAuthInterfaceService(); 387 if (userAuthInterfaceService == nullptr) { 388 IAM_LOGE("userAuthInterfaceService is nullptr"); 389 return nullptr; 390 } 391 return userAuthInterfaceService; 392 } 393 394 // Start an authentication to generate the authentication scheme and scheduling information. 395 int32_t UserAuthInterfaceService::BeginAuthentication(uint64_t contextId, const AuthSolution& param, 396 std::vector<ScheduleInfo>& infos) 397 { 398 IAM_LOGI("start"); 399 if (param.challenge.size() != sizeof(uint64_t)) { 400 IAM_LOGE("challenge copy failed"); 401 return RESULT_BAD_PARAM; 402 } 403 GlobalLock(); 404 CoAuthSchedule *schedulesGet = nullptr; 405 uint32_t scheduleIdNum = 0; 406 AuthSolutionHal solutionIn; 407 solutionIn.contextId = contextId; 408 solutionIn.userId = param.userId; 409 solutionIn.authType = static_cast<uint32_t>(param.authType); 410 solutionIn.authTrustLevel = param.authTrustLevel; 411 if (memcpy_s(&solutionIn.challenge, sizeof(uint64_t), ¶m.challenge[0], 412 param.challenge.size()) != EOK) { 413 IAM_LOGE("challenge copy failed"); 414 GlobalUnLock(); 415 return RESULT_BAD_COPY; 416 } 417 int32_t ret = GenerateSolutionFunc(solutionIn, &schedulesGet, &scheduleIdNum); 418 if (ret != RESULT_SUCCESS) { 419 IAM_LOGE("Failed to generate solution"); 420 GlobalUnLock(); 421 return ret; 422 } 423 for (uint32_t i = 0; i < scheduleIdNum; i++) { 424 ScheduleInfo temp; 425 if (!CopyScheduleInfo(schedulesGet + i, &temp)) { 426 infos.clear(); 427 ret = RESULT_GENERAL_ERROR; 428 break; 429 } 430 infos.push_back(temp); 431 } 432 free(schedulesGet); 433 GlobalUnLock(); 434 return ret; 435 } 436 437 // Update the authentication result to evaluate the authentication scheme. 438 int32_t UserAuthInterfaceService::UpdateAuthenticationResult(uint64_t contextId, 439 const std::vector<uint8_t>& scheduleResult, AuthResultInfo& info) 440 { 441 IAM_LOGI("start"); 442 GlobalLock(); 443 if (scheduleResult.size() == 0) { 444 IAM_LOGE("param is invalid"); 445 info.result = RESULT_BAD_PARAM; 446 GlobalUnLock(); 447 return RESULT_BAD_PARAM; 448 } 449 Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size()); 450 if (scheduleResultBuffer == nullptr) { 451 IAM_LOGE("scheduleTokenBuffer is null"); 452 info.result = RESULT_GENERAL_ERROR; 453 GlobalUnLock(); 454 return RESULT_NO_MEMORY; 455 } 456 UserAuthTokenHal authTokenHal; 457 info.result = RequestAuthResultFunc(contextId, scheduleResultBuffer, &authTokenHal); 458 if (info.result != RESULT_SUCCESS) { 459 IAM_LOGE("Failed to execute the function"); 460 DestoryBuffer(scheduleResultBuffer); 461 GlobalUnLock(); 462 return info.result; 463 } 464 info.token.resize(sizeof(UserAuthTokenHal)); 465 if (memcpy_s(&info.token[0], info.token.size(), &authTokenHal, sizeof(authTokenHal)) != EOK) { 466 IAM_LOGE("Failed to copy authToken"); 467 DestoryBuffer(scheduleResultBuffer); 468 GlobalUnLock(); 469 return RESULT_BAD_COPY; 470 } 471 DestoryBuffer(scheduleResultBuffer); 472 GlobalUnLock(); 473 return RESULT_SUCCESS; 474 } 475 476 // Cancel the authentication. 477 int32_t UserAuthInterfaceService::CancelAuthentication(uint64_t contextId) 478 { 479 IAM_LOGI("start"); 480 GlobalLock(); 481 uint32_t scheduleIdNum = 0; 482 int32_t ret = CancelContextFunc(contextId, nullptr, &scheduleIdNum); 483 if (ret != RESULT_SUCCESS) { 484 IAM_LOGE("Failed to execute the function"); 485 GlobalUnLock(); 486 return ret; 487 } 488 GlobalUnLock(); 489 return RESULT_SUCCESS; 490 } 491 ``` 492 493### Verification 494 495Use the [User Authentication APIs](../../application-dev/reference/apis/js-apis-useriam-userauth.md) to develop a JavaScript application and verify the application on the Hi3516D V300 development board. The sample code for verifying and canceling the authentication is as follows: 496 497```js 498// API version 8 499import userIAM_userAuth from '@ohos.userIAM.userAuth'; 500let auth = new userIAM_userAuth.UserAuth(); 501 502export default { 503 getVersion() { 504 console.info("start get version"); 505 let version = this.auth.getVersion(); 506 console.info("auth version = " + version); 507 }, 508 509 startAuth() { 510 console.info("start auth"); 511 this.auth.auth(null, userIAM_userAuth.UserAuthType.FACE, userIAM_userAuth.AuthTrustLevel.ATL1, { 512 onResult: (result, extraInfo) => { 513 try { 514 console.info("auth onResult result = " + result); 515 console.info("auth onResult extraInfo = " + JSON.stringify(extraInfo)); 516 if (result == 'SUCCESS') { 517 // Add the logic to be executed when the authentication is successful. 518 } else { 519 // Add the logic to be executed when the authentication fails. 520 } 521 } catch (e) { 522 console.info("auth onResult error = " + e); 523 } 524 }, 525 526 onAcquireInfo: (module, acquire, extraInfo) => { 527 try { 528 console.info("auth onAcquireInfo module = " + module); 529 console.info("auth onAcquireInfo acquire = " + acquire); 530 console.info("auth onAcquireInfo extraInfo = " + JSON.stringify(extraInfo)); 531 } catch (e) { 532 console.info("auth onAcquireInfo error = " + e); 533 } 534 } 535 }); 536 }, 537 538 cancelAuth() { 539 console.info("start cancel auth"); 540 // Obtain contextId using auth(). 541 let contextId = auth.auth(null, userIAM_userAuth.UserAuthType.FACE, userIAM_userAuth.AuthTrustLevel.ATL1, { 542 onResult: (result, extraInfo) => { 543 console.info("auth onResult result = " + result); 544 }, 545 546 onAcquireInfo: (module, acquire, extraInfo) => { 547 console.info("auth onAcquireInfo module = " + module); 548 } 549 }); 550 let cancelCode = this.auth.cancel(contextId); 551 if (cancelCode == userIAM_userAuth.Result.SUCCESS) { 552 console.info("Authentication canceled successfully"); 553 } else { 554 console.error("Failed to cancel authentication"); 555 } 556 } 557} 558``` 559