场景简介
短信主认证是最基本的主认证方式之一,跟用户名密码认证类似,只是在传递认证参数上有点区别。
前置步骤
流程图
集成步骤
1、初始化SDK
注意:SDK接口都需要在SDK初始化后才能调用,否则会抛出异常。
初始化SDK主要是完成SDK核心功能配置的初始化,放到EntryAbility的onCreate中初始化。
示例代码如下:
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { {
this.init();
}
/**
* 初始化SangforSDK
*
*/
init() {
let extra: Map<SFSDKExtras, string> = new Map<SFSDKExtras, string>();
let sdkFlags: number = 0;
sdkFlags = SFSDKFlags.FLAGS_HOST_APPLICATION; // 表明是单应用或者是主应用
sdkFlags |= SFSDKFlags.FLAGS_VPN_MODE_TCP; // 表明使用VPN功能中的TCP模式
SFUemSDK.getInstance().initSDK(
this.context,
SFSDKMode.MODE_VPN,
sdkFlags, extra
);
// 注册注销回调
SFUemSDK.getInstance().registerLogoutListener(this);
}
注意
SFSDKMode.MODE_SUPPORT_MUTABLE:(鸿蒙暂不支持) 初始化为该模式后,集成SDK的APP可以根据服务器的配置决定是仅具备零信任VPN的接入能力,还是具备零信任VPN的接入能力+数据防泄密能力
SFSDKMode.MODE_VPN_SANDBOX:(已废弃, 不推荐使用) 该模式是启用vpn代理功能,和启用终端安全沙箱功能(水印,分享隔离,剪切板隔离等等安全功能); 只有当集成SDK的APP在应用中心授权给用户, 用户才可以使用集成SDK的APP接入使用, 并且占用并发授权和UEM移动版授权;
SFSDKMode.MODE_VPN:(鸿蒙暂时只能用这个) 该模式表示只是启用vpn代理功能,不启用终端安全沙箱功能(水印,分享隔离,剪切板隔等等安全功能); 无论集成SDK的APP是否在应用中心授权给用户, 用户都可以使用集成SDK的APP接入使用, 并且仅占用并发授权;
沙箱文件加密功能说明:(鸿蒙暂不支持此功能)
沙箱功能中的文件加密功能是指,如果终端(手机)开启文件加密,app中需要落盘的数据会自动被加密然后重定向,以保证数据在手机存储里面的安全;
集成步骤上只需要在上面初始化的时候增加flag:SFSDKFlags.FLAGS_ENABLE_FILE_ISOLATION 并设置SDKMode为SFSDKMode.MODE_SUPPORT_MUTABLE或SFSDKMode.MODE_VPN_SANDBOX
2、设置认证回调
aTrust身份认证属于通过网络耗时操作,SDK实现时是通过代理异步回调来获取认证结果。请务必在使用认证接口前,按要求实现并注册认证结果回调。
示例代码如下:
struct BasicScenePage {
aboutToAppear(): void {
/**
* 设置认证回调,认证结果在SFAuthResultListener的onAuthSuccess、onAuthFailed、onAuthProgress中返回
* 如果不设置,将接收不到认证结果回调
*/
SFUemSDK.getInstance().setAuthResultListener(this);
}
}
3、短信主认证
示例代码如下:
let url = "";
let phoneNumber = "";
/**
* 开始短信主认证,认证结果会在认证回调onAuthSuccess,onAuthFailed,onAuthProgress中返回
* @param url 请求认证的服务器地址信息
* @param phoneNumber 手机号码:86-xxxxxxxxxxx@认证域
*/
SFUemSDK.getInstance().startPrimarySmsAuth(url, phoneNumber);
4、处理短信发送
调用startPrimarySmsAuth认证通过后会执行onAuthProgress回调,并通过nextAuthType参数告知需要认证的类型为短信主认证。当调用该回调时,会先发送短信到用户手机上,所以此时只需展示对应的短信认证UI界面,通过UI收集到短信验证码,调用doSecondaryAuth接口完成短信主认证。
示例代码如下:
/**
* 需要二次认证
*
* @param nextAuthType 认证类型
* @param message 认证信息
*/
public onAuthProcess(authType: SFAuthType, message: SFBaseMessage) {
console.info(TAG, "onAuthProcess:", authType, JSON.stringify(message));
this.loadingDialog.close();
if (authType === SFAuthType.AUTH_TYPE_PRIMARY_SMS) {
this.doSmsSecondAuth()
return
}
this.showFailDialog(`暂不支持此种认证类型(${authType}), 管理员请关掉此认证`);
}
/**
* 使用短信主认证
*/
private doSmsSecondAuth() {
let authInfo: Map<string, string> = new Map<string, string>();
let smsCode = "xxxx"; // 短信验证码
authInfo.set(SFConstants.AUTH_KEY_PRIMARYSMS_CODE, smsCode);
SFUemSDK.getInstance().doSecondaryAuth(SFAuthType.AUTH_TYPE_PRIMARY_SMS, authInfo);
}
5、认证成功
主认证成功后,如果管理员未配置二次认证,就会执行onAuthSuccess回调,至此整个认证流程就结束了,认证成功后,应用就可以正常的访问aTrust管理员配置的内网服务器资源, 执行业务代码
示例代码如下:
/**
* 认证成功
*
* @param message 认证成功message
*/
public onAuthSuccess(message: SFBaseMessage) {
console.info(TAG, "onAuthSuccess:", JSON.stringify(message));
// 认证成功之后的业务
}
6、认证失败
如果有认证失败的情况,会执行onAuthFailed回调, 在该回调中提示用户,重新开始认证
示例代码如下:
/**
* 认证失败
*
* @param message 认证失败message
*/
public onAuthFailed(message: SFBaseMessage) {
console.info(TAG, "onAuthFailed:", JSON.stringify(message));
// 重新开始认证或者其他逻辑
}
7、重新获取验证码
短信验证码有效期可以通过onAuthProgress中的参数message(参考SFSmsMessage)来获取,短信验证码失效后,可以调用接口重新获取
示例代码如下:
SFUemSDK.getInstance().getSFAuth().regetSmsCode(this);
onRegetSmsCode(success: boolean, message: SFSmsMessage) {
this.resetSendMsgButton(message.countDown);
if (success) {
promptAction.showToast({
message: '短信发送成功',
duration: 2000
});
} else {
promptAction.showToast({
message: '短信发送失败:' + JSON.stringify(message),
duration: 2000
});
}
}
8、监听注销回调
sdk使用过程中有可能出现被注销的情况,如应用主动调用注销接口、服务端管理员主动让用户下线等,所以应用监听注销回调是必须的,避免出现sdk内部已经注销了,但是应用无感知,从而出现业务异常的问题; 注意:注销回调建议在应用全生命周期内进行监听,避免出现在某个页面监听,页面销毁后,注销事件丢失的问题,可以参考SDKDemo的处理方法:在sdk初始化后就用一个单例对象注册注销回调
示例代码如下:
/**
* 注销事件监听回调,推荐在EntryAbility.ets里面监听, 避免出现认证开始了还未监听的问题
*/
SFUemSDK.getInstance().registerLogoutListener(this)
/**
* 注销结果回调
* @param type 注销类型
* @param message 注销信息
*/
onLogout(type: SFLogoutType, message: SFBaseMessage) {
let reason = "";
switch (type) {
case SFLogoutType.SFLogoutTypeUser:
reason = "用户注销";
break;
case SFLogoutType.SFLogoutTypeTicketAuthError:
reason = "免密失败";
break;
case SFLogoutType.SFLogoutTypeServerShutdown:
reason = "服务端注销";
break;
case SFLogoutType.SFLogoutTypeAuthorError:
reason = "授权失败";
break;
default:
reason = "未知";
break;
}
// 注销以后需要重新认证才能使用VPN和沙箱能力,此时根据您自己的需求可以给出提示或者跳转到登陆页面,此Demo的做法是提示并跳到首页,让用户可以重新登录
this.showLogoutDialog(`注销原因 : ${reason} code:<${message.mErrCode}> desc<${message.mErrStr}>`);
}
8、免密认证
sdk提供了免密认证的能力,即认证流程全部通过后,重启应用后,应用不需要再次使用用户名密码进行认证,可以直接调用免密认证接口进行认证上线
注意:
- 免密认证接口只需要在应用进程启动后调用一次,不用多次调用
- 免密认证不能完全取代主认证,因为用户主动注销或者管理员在控制台主动让用户下线等场景下,免密信息会失效,免密认证就会失败,所以应用需要在免密认证失败后,继续使用用户名密码进行认证,可以参考SDKDemo中的处理方式
- 免密接口返回true, 仅表示当前本地状态是支持免密状态, 真正发送免密网络请求是在接口返回之后进行的; 但应用不必担心存在时序问题, 只要免密接口返回true, 就表示可以发起资源访问了, 在内部免密请求未真正成功前, 内部会缓存应用层的资源网络请求, 等内部免密成功后会立刻代理之前缓存的请求, 如果由于网络问题导致免密失败了, 内部会不断重试直到成功(重试间隔为3s一次), 应用不必关注内部免密机制, 只要网络恢复, 内部自然能免密成功并在成功后代理已缓存和新发起的资源请求.
- 因为免密接口返回true, 不表示内部已经真正免密成功, 所以存在一种场景: 在应用进程退出期间, 用户被注销了, 此时重新打开应用, 调用免密会返回true, 但内部真正发送免密请求时, 由于用户已经注销, 此时应用会收到注销回调. 这种场景是正常的, 只要确保在调用免密前已经注册注销回调监听, 收到注销后, 就按正常注销处理逻辑,引导用户重新登录
示例代码如下:
/**
* 这里是自动免密认证接口,返回true表示认证成功,此时用户就可以进行资源访问了,
* 如果返回false,表示当前不满足自动免密条件,需要用户主动调用用户名密码认证接口
*/
if (SFUemSDK.getInstance().startAutoTicket()){
showToast("免密成功");
} else {
//继续用户名密码认证逻辑
}