场景简介
当同时存在多个app需要集成sdk,且多个app需要使用同一个用户登陆时,如果每个应用都去做用户名密码认证,不仅体验不佳,且会占用多个授权,为了解决此场景,sdk提供了专门用于主从场景的接口,只需要主应用做用户名密码认证,子应用通过接口向主应用同步授权信息即可进行免密上线
前置步骤
流程图

集成步骤
1、声明被主应用拉起的url scheme
在module.json5文件中中对应处理主应用拉起的ability中的skills标签中声明scheme协议,可以参考子应用Demo,用于主应用调用SDK接口拉起子应用进行授权,里面的scheme是固定的,但host应用填用户当前应用的包名
"uris": [
{
"scheme": "SFEasyApp",
"host": "com.sangfor.sub.demo"
}
]
2、初始化SDK
注意:SDK接口都需要在SDK初始化后才能调用,否则会抛出异常。
初始化SDK主要是完成SDK核心功能配置的初始化,放到AbilityStage的onCreate中初始化。
示例代码如下:
onCreate(): void {
this.init()
}
init() {
let extra: Map<SFSDKExtras, string> = new Map<SFSDKExtras, string>();
let sdkFlags: number = 0;
sdkFlags = SFSDKFlags.FLAGS_SUB_APPLICATION; // 设置子应用标识
sdkFlags |= SFSDKFlags.FLAGS_VPN_MODE_TCP;
sdkFlags |= SFSDKFlags.FLAGS_SDP_SERVER; // 表明对接的是SDP
SFUemSDK.getInstance().initSDK(
this.context,
SFSDKMode.MODE_SUPPORT_MUTABLE,
sdkFlags, extra
);
}
注意
SFSDKFlags.FLAGS_SUB_APPLICATION 该模式是启用vpn代理功能,和启用终端安全沙箱功能(水印,分享隔离,剪切板隔离等等安全功能); 只有当集成SDK的APP在应用中心授权给用户, 用户才可以使用集成SDK的APP接入使用, 并且占用并发授权和UEM移动版授权;
SFSDKMode.MODE_SUPPORT_MUTABLE: SFSDKMode.MODE_SUPPORT_MUTABLE
3、处理子应用Ability进入前台onForeground函数
onForeground(): void {
this.checkLogin();
}
async checkLogin() {
//先判断是否在线,在线状态无需做特殊处理,可以访问资源
const isOnlineStatus = await SFUemSDK.getInstance().getSFAuth().getAuthStatus()
if (isOnlineStatus) {
hilog.info(0x0000, 'testTag', '%{public}s', 'is online, do nothing');
return;
}
// 不在线情况下,先调用免密,如果免密返回true,也无需拉起主应用进行授权,可以访问资源
// 如果免密返回false,需要拉起主应用申请授权
const isReady = SFUemSDK.getInstance().startAutoTicket()
if (!isReady) {
// 拉起主应用授权前显示 loading,等 onAppLaunched 回调后关闭
this.showLoading('正在申请主应用授权...')
this.launchMainApp()
}
}
4、跳转主应用获取登录凭据
免密认证失败后,需要拉起主应用获取登录凭据,这里建议在拉起主应用前开始显示loading,等收到主应用拉起的回调再关闭loading
示例代码如下:
const hostAppBundleName = "com.sangfor.sdkdemo";
const result = await launch.launchApp(hostAppBundleName,
SFLaunchReason.SFLaunchReasonHostappAuthAuthorization,
"")
5、收到主应用拉起回调后可以开始访问资源
子应用被主应用拉起后,子应用收到数据完成上线后才会回调onAppLaunched监听事件,所以回调了onAppLaunched事件一定是上线成功的,此时可以把loading关闭,开始访问资源 示例代码如下:
onAppLaunched(launchInfo: SFLaunchInfo): void {
console.log("onAppLaunched with", JSON.stringify(launchInfo))
// 主应用拉起子应用完成,关闭 loading
this.closeLoading()
}
6、监听注销事件
子应用使用过程中有可能出现被注销的情况,如主应用主动调用注销接口、服务端管理员主动让用户下线等,所以子应用监听注销回调是必须的,避免出现sdk内部已经注销了,但是应用无感知,从而出现业务异常的问题;
注意:注销回调建议在应用全生命周期内进行监听,避免出现在某个页面监听,页面销毁后,注销事件丢失的问题,可以参考SubApp 在Ability中进行监听
示例代码如下:
/**
* 注销事件监听回调
*/
/**
* 注销结果回调
* @param type 注销类型
* @param message 注销信息
*/
onLogout(type: SFLogoutType, message: SFBaseMessage) {
//注销后需要拉起主应用重新授权
this.launchMainApp()
}