• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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), &param.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