员工身份(EIAM)

二次生物认证

# 文档说明

本文为您介绍iOS客户端如何接入生物认证功能。生物认证即PC端登录时借助手机指纹/面容识别功能作为多因素认证。

用户在登录PC时选择“使用认证器作为二次认证”,此时用户打开APP,确保登录状态和设备已绑定的情况下,App会查询后台是否有二次认证请求,如果有,APP会唤起手机生物识别确认是机主本人,同时APP会通知IDaaS服务端进行接下来的认证授权流程。

# 流程说明

绑定设备集成流程说明

  1. App客户端调用查询设备绑定状态方法,IDaaS SDK请求IDaaS服务端查询设备是否已绑定。
  2. 如果查询结果为没有绑定此设备,App客户端调用绑定设备方法,IDaaS SDK发起绑定流程,调起手机指纹识别/面容识别,确认是机主本人。IDaaS服务端记录本机为已绑定状态,并返回绑定成功/失败给App客户端。

二次认证流程说明

  1. 用户打开PC浏览器浏览器登录IDaaS系统,选择“使用认证器作为二次认证”,点击验证。App 客户端调用查询是否有二次认证方法,IDaaS服务端返回随机字串。
  2. App客户端拿到随机字串,用这个字串调用二次认证方法,IDaaS SDK拉起二次认证流程,调起手机指纹识别/面容识别,确认是机主本人,并发送二次认证请求到IDaaS服务端。服务端验证通过,PC网页端自动刷新状态。

解绑流程说明

  1. App客户端调用查询设备绑定状态方法,IDaaS SDK请求IDaaS服务端查询设备是否已绑定。
  2. 如果查询结果为已绑定此设备,App客户端调用解绑方法,IDaaS SDK发起解绑流程,调起手机指纹识别/面容识别,确认是机主本人,IDaaS服务端记录本机为未绑定状态,并返回解绑成功/失败给App客户端。

# 准备工作

# 获取clientID

登录IDaaS企业中心平台,点击 “资源-->应用” 选择跟自己相关的应用点击即可查看到。

# 开启二次认证

  1. 登录到IDaaS企业中心平台,点击 “认证—>认证策略”。

  2. 点击添加策略,此时会右边弹出一个策略框,输入描述,并且勾选“二次认证”和“竹云认证器(FaceID或指纹识别)”,点击确定。

  3. 如上步骤配置好后,会在登录用户中心页面,进行了一级登录后,需要二次认证的地方,会出现选项"通过竹云验证器进行验证"。

# 引入依赖包

指纹加密依赖于外部库'EllipticCurveKeyPair'

# 添加主库

AuthnCenter_common_2E.framework	  
AuthnCenter_MFA_BioVerify_2E.bundle
AuthnCenter_MFA_BioVerify_2E.framework 
1
2
3

将IDaaSSDK拖入工程,并且引入方式如下:

并且引入Pod的依赖包

pod 'JWT', '~> 3.0.0-beta.14'

pod 'EllipticCurveKeyPair'

# Targets设置

  • IDaaS二次认证生物认证SDK最低版本可兼容ios 11。

  • 设置Other Linker Flags,在你的工程文件中选择 Build Setting,在"Other Linker Flags"中加入"-ObjC -all_load"。

  • 设置bitcode为NO。

# Info.plist设置

在info.plist文件中添加生物认证权限。

Privacy - Face ID Usage Description:想使用你的面容指纹为了生物认证功能。

# 开发集成

# 一键式调起开发集成方式

本章节是APP客户端一次拉起绑定,解绑,二次认证。APP客户端只需要接入IDaaS,不需要考虑编写指纹识别/面容识别代码。

方法提供:

  1. SDK初始化
  2. 查询手机是人脸识别还是指纹识别类型,为显示在弹窗上文字判断(可选工具方法)
  3. 查询设备绑定状态
  4. 绑定设备
  5. 解绑设备
  6. 查询目前PC端是否发起了二次认证
  7. 二次认证方法

# SDK初始化

IDaaS SDK提供一个初始化方法,您可在初始化方法里填入租户,clientID和是否打开log日志打印。

初始化方法的示例:

在appdelegate中引用头文件如下
#import <AuthnCenter_common_2E/BCIDACommonManager.h>

  
//在appdelegate 中的didFinishLaunchingWithOptions方法中
//1. 基本配置初始化
[[[[[BCIDACommonManager sharedInstance] initWithDomain:@"https://你的后台租户.com"] initWithClientID:@"后台租户clientID"] initWithSSLCerVerification:NO] setLogEnabled:YES] ;
1
2
3
4
5
6
7

基本配置初始化主类BCIDACommonManager方法简介:

/**
  * 函数名:sharedInstance
   * @param 无
   * @return 单例对象实例类
 */
+ (instancetype )sharedInstance ;

/**
  * 函数名:initWithDomain
   * @param domain,以https://开头,以.com结尾。
   * @return 实例类
 */
-(BCIDACommonManager)initWithDomain:(NSString)domain

/**
  * 函数名:initWithClientID
   * @param client id。
   * @return 实例类
 */
-(BCIDACommonManager)initWithClientID:(NSString)clientID;

/**
  * 函数名:setLogEnabled
   * @param 布尔值是否开启log。
   * @return 实例类
 */
-(void)setLogEnabled:(BOOL)enable;

/**
  * 函数名:initWithSSLCerVerification
   * @param 布尔值设置ssl证书是否开启检测。
   * @return 实例类
 */
-(BCIDACommonManager*)initWithSSLCerVerification:(bool)sslCerVerification;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 查询手机是人脸识别还是指纹识别类型

这是一个可选方法,查询手机是人脸识别还是指纹识别。为人脸识别图标和指纹识别图标动态加载做准备。

方法示例:

//导入请求头
#import <AuthnCenter_MFA_BioVerify_2E/AuthnCenter_MFA_BioVerify_2E.h>

//点击(触发)事件
[BCIDAFingerPrintManager checkFingerPrintTypeWithCallback:^(NSString *checkFcode, id checkFdata) {
        NSLog(@"checkFinger方法返回%@==%@",checkFcode,checkFdata);

        if([checkFcode isEqualToString:@"3"]){
           [BDEFAULTS setObject:@"FaceID" forKey:BC_Phone_FaceID_TouchID_Type];
           [BDEFAULTS synchronize];
        }else if([checkFcode isEqualToString:@"4"]){
            [BDEFAULTS setObject:@"TouchID" forKey:BC_Phone_FaceID_TouchID_Type];
            [BDEFAULTS synchronize];
        }
    }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

BCIDAFingerPrintManager 方法简介:

/**
BCIDAFingerCheckTypeBlock回调函数包含 NSString* checkFcode,id checkFdata
 checkFcode=2,不支持指纹验证
 checkFcode=3:面容
 checkFcode=4:指纹
 checkFcode=5:支持生物识别但是没有设置
 checkFcode=6:锁屏密码没有设置,当生物识别没有的情况下
 checkFcode=7:生物识别被锁住了
 checkFcode=8:用户取消了生物识别
 checkFcode=9:其他原因请见checkFdata返回字串
 */
+(void)checkFingerPrintTypeWithCallback:(BCIDAFingerCheckTypeBlock)callBack;
1
2
3
4
5
6
7
8
9
10
11
12

# 查询设备绑定状态

在任何需要的地方(绑定、解绑前、二次认证前,提示用户开启生物识别引导页前)调用此方法,代码示例如下:

//导入请求头
#import <AuthnCenter_MFA_BioVerify_2E/AuthnCenter_MFA_BioVerify_2E.h>


//点击(触发)事件
[[BCIDAMfaBioDeviceBindManager sharedInstance] checkDeviceStatusWithIDToken:_company.user.id_token andWithCallBack:^(NSString * _Nonnull statuscode, id  _Nonnull statusdata) {
       
        dispatch_async(dispatch_get_main_queue(), ^{
            if([statuscode isEqualToString:@"101"]){//已绑定
               
            }else if([statuscode isEqualToString:@"102"]){//未绑定
                
                
            }else{//错误码
              
            }
        });
        
    }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

BCIDAMfaBioDeviceBindManager对象方法简介:

/**
  * 函数名:sharedInstance
   * @param 无
   * @return 单例对象实例类
 */
+ (instancetype )sharedInstance ;

/**BCMFABioDeviceStatusCompleteHandler回调函数包含NSString * _Nonnull statuscode,id statusdata
  入参:
 idToken :登录成功后的在有效期内的idtoken
**/
-(void)checkDeviceStatusWithIDToken:(NSString*)idToken andWithCallBack:(BCMFABioDeviceStatusCompleteHandler)callBack;
1
2
3
4
5
6
7
8
9
10
11
12

BCMFABioDeviceStatusCompleteHandler回调函数返回码:

statuscode码 说明
statuscode=101 statusdata=已绑定
statuscode=102 statusdata=未绑定
statuscode=错误码(请参考IDaaS返回码) statusdata=错误码描述

# 绑定设备

在需要绑定设备的情况下,请先调用上面查询设备绑定状态后再调用此方法。

//导入请求头
#import <AuthnCenter_MFA_BioVerify_2E/AuthnCenter_MFA_BioVerify_2E.h>

//点击(触发)事件
 [[BCIDAMfaBioDeviceBindManager sharedInstance] bindDeviceWithIDToken:_company.user.id_token andWithUserID:_company.user.userid andWithCallBack:^(NSString * _Nonnull bindscode, id  _Nonnull bindsdata) {
          

            dispatch_async(dispatch_get_main_queue(), ^{
               

                if([bindscode isEqualToString:@"0"]){//绑定成功
                  
                }else if([bindscode isEqualToString:@"COM.0217"]){//token失效
              
                }else{//绑定不成功
                
                }
            });
        }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

BCIDAMfaBioDeviceBindManager对象方法简介:

/**
  * 函数名:sharedInstance
   * @param 无
   * @return 单例对象实例类
 */
+ (instancetype )sharedInstance ;

/**BCMFABioDeviceBindCompleteHandler回调函数包含:NSString * _Nonnull bindscode,id bindsdata
入参:
 idToken :登录成功后的在有效期内的idtoken
  userID :用于作为此用户在这个app唯一的标识,用于生物认证生成公私钥,保证用户在此app的唯一性。
**/
-(void)bindDeviceWithIDToken:(NSString*)idToken andWithUserID:(NSString*)userID andWithCallBack:(BCMFABioDeviceBindCompleteHandler)callBack;
1
2
3
4
5
6
7
8
9
10
11
12
13

BCMFABioDeviceBindCompleteHandler回调返回值:

本地生物识别错误码 备注
bindscode=2 不支持指纹验证
bindscode=5 支持生物识别但是没有设置
bindscode=6 锁屏密码没有设置,当生物识别没有的情况下
bindscode=7 生物识别被锁住了
bindscode=8 用户取消了生物识别
bindscode=110 生物识别失败
bindscode=102 按下home键取消了生物识别
网络请求错误码
bindscode=1 入参缺失
bindscode=101 生成rsa公钥时出错
bindscode=0 绑定成功
bindscode=104 绑定失败
bindscode=其他后端错误码 详情请见最后页IDaaS错误码

# 解绑设备

在需要解绑设备的情况下,请先调用上面查询设备绑定状态后再调用此方法。

代码示例:

//导入请求头
#import <AuthnCenter_MFA_BioVerify_2E/AuthnCenter_MFA_BioVerify_2E.h>

//触发事件
[[BCIDAMfaBioDeviceBindManager sharedInstance] unbindDeviceWithIDToken:id_token andWithCallBack:^(NSString * _Nonnull unbincode, id  _Nonnull unbindata) {
        

        dispatch_async(dispatch_get_main_queue(), ^{
            if([unbincode isEqualToString:@"0"])//解绑成功
            {
               

            }else{//解绑不成功
             
            }

          
        });
    }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

BCIDAMfaBioDeviceBindManager对象的方法简介:

/**
  * 函数名:sharedInstance
   * @param 无
   * @return 单例对象实例类
 */
+ (instancetype )sharedInstance ;

/**BCMFABioDeviceUnbindCompleteHandler回调函数包含:NSString * _Nonnull unbincode,id unbindata
入参:
 idToken :登录成功后的在有效期内的idtoken

**/


-(void)unbindDeviceWithIDToken:(NSString*)idToken andWithCallBack:(BCMFABioDeviceUnbindCompleteHandler)callBack;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

BCMFABioDeviceUnbindCompleteHandler回调返回值:

本地生物识别错误码 备注
bindscode=2 不支持指纹验证
bindscode=5 支持生物识别但是没有设置
bindscode=6 锁屏密码没有设置,当生物识别没有的情况下
bindscode=7 生物识别被锁住了
bindscode=8 用户取消了生物识别
bindscode=110 生物识别失败
bindscode=102 按下home键取消了生物识别
网络请求等错误码
bindscode=1 入参缺失
code=105 解绑失败
bindscode=0 解绑成功
bindscode=其他后端错误码 详情请见最后页IDaaS错误码

# 查询目前PC端是否发起了二次认证

在已登录拿到有效的idtoken情况下,在已经绑定的情况下,查询目前PC端发起了二次认证。

代码示例:

//引入头文件
#import <AuthnCenter_MFA_BioVerify_2E/AuthnCenter_MFA_BioVerify_2E.h>

//触发方法 
 [[BCIDAMfaBioVerifyManager sharedInstance] checkIfMFAAvailableWithidToken:_company.user.id_token andWithCallBack:^(NSString * _Nonnull code, id  _Nonnull data) {
       
        dispatch_async(dispatch_get_main_queue(), ^{
    
            if([code isEqualToString:@"0"]&&![StringUtil isBlankString:(NSString*)data]){
                    NSString* randomS= (NSString*)data;//拿到的随机数,用于二次认证验证方法入参
                   
               [BCAlertPopManager podAlertWithTwoSectionWithTitle:nil andWithMessage:@"您正在进行二次验证操作" inVC:self andCancelSectionName:@"取消" andFirstSelectorName:@"cancelSecondVerifyFingerPrint" andSecondSecName:@"去验证" andSecondSelectorName:@"gotoSecondVerify"];
                    
              
                }else{//查到二次认证的报错误码
                    
                  
                }

        });
        
    }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

BCIDAMfaBioVerifyManager对象方法简介:

/**
  * 函数名:sharedInstance
   * @param 无
   * @return 单例对象实例类
 */
+ (instancetype )sharedInstance;

/**BCMFABioVerifyCheckCompleteHandler回调函数包含NSString * _Nonnull code,id data
入参:
idToken :登录成功后的在有效期内的idtoken
**/

-(void)checkIfMFAAvailableWithidToken:(NSString*)idToken andWithCallBack:(BCMFABioVerifyCheckCompleteHandler)callBack;
1
2
3
4
5
6
7
8
9
10
11
12
13

BCMFABioVerifyCheckCompleteHandler返回值:

code码 说明
code=1 参数缺失
code=0 目前有二次认证需要被完成,data返回随机数字符串,此字符串用于下面二次认证方法入参
code=2 目前没有二次认证需要被完成

# 二次认证方法

当上一个方法查询到PC端发起了二次认证,而且拿到了随机数,此时,调用此方法SDK拉起二次认证流程,完成扫脸/指纹验证,发送验证结果到后端,完成二次认证。

代码示例:

 //引入头文件
#import <AuthnCenter_MFA_BioVerify_2E/AuthnCenter_MFA_BioVerify_2E.h>

//触发方法 
 [[BCIDAMfaBioVerifyManager sharedInstance] verifyMFAResponseWithUserID:_company.user.userid andWithIdToken:_company.user.id_token andRandomStr:_randomStr andWithCallBack:^(NSString * _Nonnull code, id  _Nonnull data) {

   
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if([code isEqualToString:@"0"]){
              
                [MBProgressHUD showSuccess:@"二次认证成功"];


            }else{//二次认证失败
                
            }
        });
    }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

BCIDAMfaBioVerifyManager对象方法简介:

/**
  * 函数名:sharedInstance
   * @param 无
   * @return 单例对象实例类
 */
+ (instancetype )sharedInstance;

/**BCMFABioVerifyCompleteHandler回调函数包含NSString * _Nonnull code,id data
入参:
idToken :登录成功后的在有效期内的idtoken
userid:在绑定方法入参的同样的userid
randomStr:在上一个查询是否有二次认证的方法得到的随机字符串
**/
-(void)verifyMFAResponseWithUserID:(NSString*)userid andWithIdToken:(NSString*)idToken andRandomStr:(NSString*)randomStr andWithCallBack:(BCMFABioVerifyCompleteHandler)callBack;
1
2
3
4
5
6
7
8
9
10
11
12
13
14

BCMFABioVerifyCompleteHandler返回值:

code码 说明
code=1 入参缺失
code=101 签名方法出错,请联系管理员
code=2 二次认证失败
code=0 二次认证成功
code=其他 参照IDaaS后台错误码,在页尾

# API的调用方式集成方法

此章节是介绍如何以API的形式接入生物认证二次认证SDK,开发者需要依照开篇流程图自己串起整个流程。包括编写生物认证代码调起指纹认证或面容认证,搭配SDK提供的工具类使用。

# API列表

  1. SDK初始化。

  2. 查询设备绑定状态API

  3. 绑定API

  4. 解绑API

  5. 二次认证API

# SDK初始化

IDaaS SDK初始化方法的示例:

在appdelegate中引用头文件如下
#import <AuthnCenter_common_2C/BCIDACommonManager.h>

//在appdelegate 中的didFinishLaunchingWithOptions方法中
//1. 基本配置初始化
[[[[[BCIDACommonManager sharedInstance] initWithDomain:@"https://你的后台租户.com"] initWithClientID:@"后台租户clientID"] initWithSSLCerVerification:NO] setLogEnabled:YES] ;
1
2
3
4
5
6

# 查询设备绑定状态API

在任何需要的地方(绑定、解绑前、二次认证前,提示用户开启生物识别引导页前)调用此方法,代码示例如下:

//导入请求头
#import <AuthnCenter_MFA_BioVerify_2E/AuthnCenter_MFA_BioVerify_2E.h>


//点击(触发)事件
[[BCIDAMfaBioDeviceBindManager sharedInstance] checkDeviceStatusWithIDToken:_company.user.id_token andWithCallBack:^(NSString * _Nonnull statuscode, id  _Nonnull statusdata) {
       
        dispatch_async(dispatch_get_main_queue(), ^{
            if([statuscode isEqualToString:@"101"]){//已绑定
               
            }else if([statuscode isEqualToString:@"102"]){//未绑定
                
                
            }else{//错误码
              
            }
        });
        
    }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

BCIDAMfaBioDeviceBindManager对象方法简介:

/**
  * 函数名:sharedInstance
   * @param 无
   * @return 单例对象实例类
 */
+ (instancetype )sharedInstance ;

/**BCMFABioDeviceStatusCompleteHandler回调函数包含NSString * _Nonnull statuscode,id statusdata
  入参:
 idToken :登录成功后的在有效期内的idtoken
**/
-(void)checkDeviceStatusWithIDToken:(NSString*)idToken andWithCallBack:(BCMFABioDeviceStatusCompleteHandler)callBack;
1
2
3
4
5
6
7
8
9
10
11
12

BCMFABioDeviceStatusCompleteHandler回调函数返回码:

statuscode码 说明
statuscode=101 statusdata=已绑定
statuscode=102 statusdata=未绑定
statuscode=错误码(请参考IDaaS返回码) statusdata=错误码描述

# 绑定API

代码示例,在没有绑定的情况下,按照下面调用顺序调用:

  1. 调用指纹面容认证,认证成功后。

  2. 调用工具类BCIDAFingerPrintVerifyManager里方法getPublicKeywithUserid,成功获取到公钥字串。

  3. 调用绑定方法BCIDAMfaBioAPIManager的bindDeviceWithidToken:idtoken andPublicKey:pubKey。

//1.调用指纹面容认证,认证成功后调用
  LAContext *context = [[LAContext alloc] init];
  [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:localizedReason reply:^(BOOL success, NSError * _Nullable error) {
            
      if (success) {//验证成功
//2.调用工具类生成加密公钥,入参userid可以代表用户唯一的字符串,并且是永久保存在手机内,此用户id变了,公钥也会变,原有的绑定关系将不存在
// 3.将公钥传入绑定方法
        [[BCIDAFingerPrintVerifyManager sharedInstance] getPublicKeywithUserid:_userID CallBack:^(NSString * _Nonnull gencode, id  _Nonnull gendata) {

            if([gencode isEqualToString:@"0"]){
                NSString* pubKey=(NSString*)gendata;
                [[BCIDAMfaBioAPIManager sharedInstance] bindDeviceWithidToken:idtoken andPublicKey:pubKey andWithCallBack:^(id  _Nonnull bindData) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        
                        NSDictionary* dic=(NSDictionary*)bindData;
                        NSString* code= [dic objectForKey:@"code"];
                        NSString* message=[dic objectForKey:@"message"];
                        if([code isEqualToString:@"0"]){
                            NSNumber* dataN=(NSNumber*)[dic objectForKey:@"data"];
                            if(dataN!=nil&&dataN!=[NSNull null]){
                                BOOL flag= [dataN boolValue];
                                if(flag){//成功
                                    [self.bindSwitch setOn:YES];
                                    NSString* errstr=[NSString stringWithFormat:@"绑定成功"];
                                    
                                    [MBProgressHUD showSuccess:errstr];
                                }else{//失败
                                    
                                    NSString* errstr=[NSString stringWithFormat:@"绑定失败"];
                                    [MBProgressHUD showError:errstr];
                                }
                            }else{
                                NSString* errstr=[NSString stringWithFormat:@"绑定失败"];
                                [MBProgressHUD showError:errstr];
                            }
                            
                        }else{
                            NSString* errstr=[NSString stringWithFormat:@"绑定失败:%@--%@",code,message];
                            [MBProgressHUD showError:errstr];
                        }
                    });
                    
                    
                }];
                
            }else{
                
                [MBProgressHUD showError:@"公钥获取错误,请联系管理员"];
            }
        }];
              
            }
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

BCIDAFingerPrintVerifyManager对象简介:

+ (instancetype )sharedInstance ;

/**获得publickey,如果没有就生成,如果已经生成的,就获取原有的,
BCIDAFingerPrintKeypairGenerateCompleteHandler 返回NSString * _Nonnull gencode,id gendata
gencode=0 gendata=公钥
gencode=101 gendata=错误描述
**/

-(void)getPublicKeywithUserid:(NSString*)userid CallBack (BCIDAFingerPrintKeypairGenerateCompleteHandler)callBack;
1
2
3
4
5
6
7
8
9

BCIDAMfaBioAPIManager对象简介:

+ (instancetype )sharedInstance ;
/**
绑定,入参idtoken
        publicKey(上一个方法产生的公钥)
     BCMFABioAPIBindCompleteHandler回调返回NSDictionary对象
    
**/
-(void)bindDeviceWithidToken:(NSString*)idToken andPublicKey:(NSString*)publicKey andWithCallBack:(BCMFABioAPIBindCompleteHandler)callBack;
1
2
3
4
5
6
7
8

回调函数返回NSDictionary对象:

参数名 中文名称 类型 描述
code 返回状态码 String 0为成功,其他为错误码
data 返回内容 String 绑定成功,返回true
message 返回信息 String 发生错误时,返回具体错误信息

# 解绑API

代码示例,在没有绑定的情况下,按照下面调用顺序调用:

  1. 调用指纹面容认证,认证成功后。
  2. 调用BCIDAMfaBioAPIManager的unbindDeviceAPIWithIDToken:idtoken andWithCallBack方法解绑。
//1.调用指纹面容认证,认证成功后调用
  LAContext *context = [[LAContext alloc] init];
  [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:localizedReason reply:^(BOOL success, NSError * _Nullable error) {
            
      if (success) {//验证成功
      
        [[BCIDAMfaBioAPIManager sharedInstance] unbindDeviceAPIWithIDToken:idtoken andWithCallBack:^(id  _Nonnull unbindData) {
            dispatch_async(dispatch_get_main_queue(), ^{
                
                NSDictionary* dic=(NSDictionary*)unbindData;
                NSString* code= [dic objectForKey:@"code"];
                NSString* message=[dic objectForKey:@"message"];
                if([code isEqualToString:@"0"]){
                    NSNumber* dataN=(NSNumber*)[dic objectForKey:@"data"];
                    if(dataN!=nil&&dataN!=[NSNull null]){
                        BOOL flag= [dataN boolValue];
                        if(flag){//解绑成功
                            [self.bindSwitch setOn:NO];

                            NSString* errstr=[NSString stringWithFormat:@"解绑成功"];
                            [MBProgressHUD showSuccess:errstr];
                        }else{//解绑失败
                            
                            NSString* errstr=[NSString stringWithFormat:@"解绑失败"];
                            [MBProgressHUD showError:errstr];
                        }
                    }else{
                        NSString* errstr=[NSString stringWithFormat:@"解绑失败"];
                        [MBProgressHUD showError:errstr];
                    }
                    
                }else{
                    NSString* errstr=[NSString stringWithFormat:@"解绑失败:%@--%@",code,message];
                    [MBProgressHUD showError:errstr];
                }
            });
        }];
      
      
      }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

BCIDAMfaBioAPIManager对象简介:

+ (instancetype )sharedInstance ;

/**解绑
入参:idToken
BCMFABioAPIUnBindCompleteHandler 回调返回NSDictionary对象
**/
-(void)unbindDeviceAPIWithIDToken:(NSString*)idToken andWithCallBack:(BCMFABioAPIUnBindCompleteHandler)callBack;
1
2
3
4
5
6
7

回调函数返回NSDictionary对象:

参数名 中文名称 类型 描述
code 返回状态码 String 0为成功,其他为错误码
data 返回内容 String 成功,返回true
message 返回信息 String 发生错误时,返回具体错误信息

# 二次认证API

代码示例,在确定已绑定的情况下才能查询是否可以使用二次认证,这里不需要开发者写生物识别代码,API在加签的时候会自带。按照下面调用顺序:

  1. 查询是否PC端发起了二次认证用BCIDAMfaBioAPIManager的checkIFMfaBioRequestAvailableWithIdToken:idToken andWithCallBack,有二次认证的返回随机字串,留作下面入参。

  2. 有二次认证,弹框询问用户是否验证。

  3. 用户点击去验证,调用工具类BCIDAFingerPrintVerifyManager的signDataByPrivateKeywithUserid:_userID WithStr:_randomStr andWithCallBack,并且将1中得到的随机字串入参。返回签名了的随机字串,签名这个环节会调起指纹或面容验证。

  4. 调用BCIDAMfaBioAPIManager的 responseToMfaBioWithIdToken:idtoken andWithSignedStr:signddata andWithCallBack方法,将3中签名了的随机字串作为signddata入参。

//查询是否有二次认证已发起了
-(void)mfaCheckWithidToken:(NSString*)idToken{
    
    [[BCIDAMfaBioAPIManager sharedInstance] checkIFMfaBioRequestAvailableWithIdToken:idToken andWithCallBack:^(id  _Nonnull mfaReData) {
        dispatch_async(dispatch_get_main_queue(), ^{
            
            NSDictionary* dic=(NSDictionary*)mfaReData;
            NSString* co=[dic objectForKey:@"code"];
            NSDictionary* da=(NSDictionary*)[dic objectForKey:@"data"];
            NSString* mesg=[dic objectForKey:@"message"];
            
            if([co isEqualToString:@"0"]){
                if(da!=nil){
                    NSString* randomS=  [da objectForKey:@"random"];
                    NSString* clientId=[da objectForKey:@"clientId"];
                    NSString* clientNameS=[da objectForKey:@"clientName"];
                    if(![BCIDACommonStringUtils isEmptyString:randomS]){
                        _randomStr=randomS;
                        [BCAlertPopManager podAlertWithTwoSectionWithTitle:nil andWithMessage:@"有需要完成的二次认证" inVC:self andCancelSectionName:@"关闭" andFirstSelectorName:nil andSecondSecName:@"去验证" andSecondSelectorName:@"goMFaVerify"];

                    }else{
                        [MBProgressHUD showMessage:@"没有二次认证需要验证"];
                    }
                }else{
                    [MBProgressHUD showMessage:@"没有二次认证需要验证"];
                }
    
                
            }
            
            
        });
    }];
    
    
}

//去二次认证
-(void)goMFaVerify{
    NSString* idtoken=  [BCIDADEFAULTS objectForKey:idTokenSaveAll];
      if(idtoken==nil||[idtoken isEqualToString:@""]){
          [MBProgressHUD showError:@"登录失效,请重新登录"];
          return;
      }
    //1.用户拿到随机串后,要把随机串用以下方法进行签名,签名结果放入二次认证方法中入参
    [[BCIDAFingerPrintVerifyManager sharedInstance] signDataByPrivateKeywithUserid:_userID WithStr:_randomStr andWithCallBack:^(NSString * _Nonnull signdcode, id  _Nonnull signddata) {
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if ([signdcode isEqualToString:@"0"]) {
                NSString* signda=(NSString*)signddata;
                [[BCIDAMfaBioAPIManager sharedInstance] responseToMfaBioWithIdToken:idtoken andWithSignedStr:signddata andWithCallBack:^(id  _Nonnull mfaReData) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        
                        NSDictionary* dic=(NSDictionary*)mfaReData;
                        NSString* code=[dic objectForKey:@"code"];
                        NSNumber* dataflag=(NSNumber*)[dic objectForKey:@"data"];
                        NSString* message=[dic objectForKey:@"message"];
                        if([code isEqualToString:@"0"]){
                            if(dataflag!=nil&&dataflag!=[NSNull null]){
                                BOOL flag= [dataflag boolValue];
                                if(flag){
                                    [MBProgressHUD showSuccess:@"二次认证成功"];
                                }else{
                                    [MBProgressHUD showError:@"二次认证失败"];
                                }
                            }else{
                                [MBProgressHUD showError:@"二次认证失败"];
                            }
                        }else{
                            NSString* errStr=[NSString stringWithFormat:@"二次认证失败:%@--%@",code,message];
                            [MBProgressHUD showError:errStr];
                        }
                        
                    });
                    
                }];
                
            }else{
                [MBProgressHUD showError:@"随机串签名错误"] ;
                
            }
        });
    }];
    
   
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

BCIDAMfaBioAPIManager对象方法简介:

+ (instancetype )sharedInstance ;

/**查询是否已发起了二次认证
   入参:idToken
   回调返回NSDictionary对象
**/
-(void)checkIFMfaBioRequestAvailableWithIdToken:(NSString*)idToken andWithCallBack:(BCMFABioAPIRequestAvailableCompleteHandler)callBack;

/**去二次认证
  入参:idToken
       signedStr:上一个方法返回的随机字串加签后
       回调返回NSDictionary对象
       
**/
-(void)responseToMfaBioWithIdToken:(NSString*)idToken andWithSignedStr:(NSString*)signedStr andWithCallBack:(BCMFABioAPIResponseToMfaCompleteHandler)callBack;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

回调返回值:

BCMFABioAPIRequestAvailableCompleteHandler成功回调返回:
{
    "code": "0",
    "data":  
            {              
                "random":"231123",//随机串,需要加签才能用作二次认证入参
               "clientId":"qwwmx651",
               "clientName":"华为云"
            }
        ,
    "message": null
}
错误返回是code=0,message给出错误描述

BCMFABioAPIResponseToMfaCompleteHandler成功回调返回:
{
    "code": "0",
    "data":true,//操作成功,返回YES,失败返回NO
    "message": null
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

加签工具类BCIDAFingerPrintVerifyManager的简介:

+ (instancetype )sharedInstance ;

/**
将字串签名
入参:userid代表用户唯一性,和绑定时候使用的是同一个
    signStr从查询是否有二次认证接口得到的随机字串
    回调返回NSString * _Nonnull signdcode,id signddata
    signdcode=0,data返回签名好的随机字串
    signdcode=错误码,data返回错误信息
**/
-(void)signDataByPrivateKeywithUserid:(NSString*)userid WithStr:(NSString*)signStr andWithCallBack:(BCIDAFingerPrintSignDataCompleteHandler)callBack;
1
2
3
4
5
6
7
8
9
10
11

# 返回码

状态码 错误码 (error_code) 错误说明 (error_msg) 处理措施
400 IDAAS.SDK.COMMON.1001 Parameter {0} cannot be left blank
参数 {0} 不能为空
400 IDAAS.SDK.COMMON.1002 The {0} parameter format is incorrect
参数 {0} 格式错误
400 IDAAS.SDK.COMMON.1003 Device information is incomplete
设备信息不完整
400 IDAAS.SDK.COMMON.1004 Signature decryption error
签名解密错误
400 IDAAS.SDK.COMMON.1005 The {0} has failed
{0} 已失效
400 IDAAS.SDK.COMMON.1006 The {0} parameter error
{0} 参数错误
400 IDAAS.SDK.COMMON.1007 The {0} parameter type error
{0}参数类型错误
500 IDAAS.SDK.COMMON.1008 The system is busy. Try again later
系统繁忙。稍后再试
400 IDAAS.SDK.COMMON.1009 Unknown authentication configuration
未知的认证配置
400 IDAAS.SDK.COMMON.1010 Failed to obtain the enterprise center global configuration
获取企业中心全局配置失败
400 IDAAS.SDK.COMMON.1011 Failed to obtain the international area code configuration
获取国际区号配置失败
400 IDAAS.SDK.COMMON.1012 The x-client-ID is incorrect and the corresponding application cannot be found
X-client-id错误,找不到对应的应用
400 IDAAS.SDK.COMMON.1013 The corresponding user is not found
未找到对应的用户
400 IDAAS.SDK.COMMON.1014 Application private key not found
未找到应用私钥
400 IDAAS.SDK.LOGIN.1001 Error calling interface {0}
调用 {0} 接口出错
400 IDAAS.SDK.LOGIN.1002 User not bound
用户未绑定
400 IDAAS.SDK.LOGIN.1003 The user has been locked due to too many unsuccessful login attempts. It will be unlocked in {0} minutes and {1} seconds
由于多次登录失败,用户已被锁定。 它将在 {0} 分钟和 {1} 秒内解锁
400 IDAAS.SDK.LOGIN.1004 Failed to obtain the password policy
获取密码策略错误
400 IDAAS.SDK.LOGIN.1005 Invalid username or password. Remaining login attempts: {0}
无效的用户名或密码。 其余登录尝试次数:{0}
400 IDAAS.SDK.LOGIN.1006 Configuration error, unable to find wechat authentication source
配置错误,找不到微信认证源
400 IDAAS.SDK.LOGIN.1007 Configuration error, unable to find alipay authentication source
配置错误,找不到支付宝认证源
400 IDAAS.SDK.LOGIN.1008 The configuration is incorrect. The one-click login authentication source cannot be found
配置错误,无法找到一键登录认证源
400 IDAAS.SDK.SMS.1001 {0} slide base map is not initialized successfully, please check the path
{0} 滑动底图未初始化成功,请检查路径
400 IDAAS.SDK.SMS.1002 {0} verification code coordinate resolution failed
{0} 验证码坐标解析失败
400 IDAAS.SDK.SMS.1003 {0} verification code coordinate verification fails
{0} 验证码坐标校验失败
400 IDAAS.SDK.SMS.1004 The graphic verification code is incorrect
图形验证码校验错误
400 IDAAS.SDK.SMS.1005 SMS verification code verification is incorrect
短信验证码验证错误
400 IDAAS.SDK.SMS.1006 The email verification code is incorrect
邮件验证码验证错误
400 IDAAS.SDK.SMS.1007 Sending scenario does not exist
发送场景不存在
400 IDAAS.SDK.SMS.1008 Failed to send the verification code
发送验证码失败
400 IDAAS.SDK.SOCIAL.1001 The social account is unbound incorrectly
社交账号解绑错误
400 IDAAS.SDK.SOCIAL.1002 The social account has been bound, please unbind it first
社交账号已绑定,请先解绑
400 IDAAS.SDK.PWD.1001 The password length is incorrect
密码长度错误
400 IDAAS.SDK.PWD.1002 The password cannot be the username
密码不能为用户名
400 IDAAS.SDK.PWD.1003 Your password complexity is low
你的密码复杂度过低
400 IDAAS.SDK.PWD.1004 The password is weak
密码很弱
400 IDAAS.SDK.PWD.1005 The password is used before, cannot be used again
该密码已被使用过,不能再次使用
400 IDAAS.SDK.PWD.1006 Password cannot username in reverse order
密码不能是用户名的倒序
400 IDAAS.SDK.PWD.1007 The number of repeated password characters exceeded the upper limit
密码重复字符数超过限制
400 IDAAS.SDK.PWD.1008 Password cannot contain :username, phone number, email prefix, name in PinYing
密码不能包含:用户名、电话号码、邮件前缀、拼音名
400 IDAAS.SDK.MFA.1001 The mobile doesn't match the user
手机号和用户不匹配
400 IDAAS.SDK.MFA.1002 The access control policy is incorrect
访问控制策略配置错误
400 IDAAS.SDK.MFA.1003 Access control authentication source type conversion error
访问控制身份验证源类型转换错误