场景简介
1、用户名密码认证对于用户来说只需要提交username和password参数,但对于零信任服务端来说支持多种账号密码认证方式,主要有:本地账号密码认证、ldap认证、radius认证、http(s)认证,其中本地账号密码是将用户名密码存储在零信任设备,其他认证则需要对接外部认证服务器,将认证信息传递给外部认证服务器进行认证;
2、用户名密码认证不仅仅用于传递密码参数,可以通过password字段传递token或者json格式的认证信息字符串给后端统一认证服务器,用于实现APP与SDK的单点登陆;
3、用户名密码认证是最基本也是使用最多的主认证方式,熟悉了用户名密码认证流程后,要实现其他类型的主认证流程是完全一致的,只是在传递认证参数上有点区别。有需求时参考MainApp中的BasicSceneViewController实现。
前置步骤
在实际集成之前,我们要确保已经进行过开发准备
流程图
集成步骤
1、初始化SDK
注意:SDK接口都需要在SDK初始化后才能调用,否则会抛出异常。
初始化SDK主要是完成SDK核心功能配置的初始化,只能放到AppDelegate的application:didFinishLaunchingWithOptions:中初始化。
示例代码如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
/**
* SDK的初始化模式只能放在didFinishLaunchingWithOptions中
* 建议配置为SFSDKModeSupportMutable,表示当前应用的能力(零信任VPN的接入能力和数据防泄密能力)可以根据服务端配置动态变更
* 配置为SFSDKFlagsHostApplication,表示当前集成应用是主应用。
*/
SFSDKMode mode = SFSDKModeSupportMutable;
[[SFUemSDK sharedInstance] initSDK:mode
flags:SFSDKFlagsHostApplication
extra:nil];
...
}
注意
SFSDKModeSupportMutable:(推荐使用模式) 初始化为该模式后,集成SDK的APP可以根据服务器的配置决定是仅具备零信任VPN的接入能力,还是具备零信任VPN的接入能力+数据防泄密能力
SFSDKModeSupportVpnSandbox:(已废弃, 不推荐使用) 该模式是启用vpn代理功能,和启用终端安全沙箱功能(水印,截屏防护,剪切板隔离,分享隔离等等安全功能); 只有当集成SDK的APP在应用中心授权给用户, 用户才可以使用集成SDK的APP接入使用, 并且占用并发授权和UEM移动版授权;
SFSDKModeSupportVpn:(已废弃, 不推荐使用) 该模式表示只是启用vpn代理功能,不启用终端安全沙箱功能(水印,截屏防护,剪切板隔离,分享隔离等等安全功能); 无论集成SDK的APP是否在应用中心授权给用户, 用户都可以使用集成SDK的APP接入使用, 并且仅占用并发授权;
2、设置认证回调
aTrust身份认证属于通过网络耗时操作,SDK实现是通过代理异步回调来获取认证结果。请务必在使用认证接口前,按要求实现并注册认证结果回调。
示例代码如下:
@implementation BasicSceneViewController
- (void)viewDidLoad {
...
[[SFUemSDK sharedInstance] setAuthResultDelegate:self];
...
}
@end
3、用户名密码主认证
- 用户名密码认证接口可以用于LOCAL(账号认证), LDAP认证, HTTP(S)账号认证, Radius账号认证, 这四种认证方式中只有LOCAL(账号认证) 时用户名无需加认证域, 其他三种认证方式的用户名是携带认证域的,格式上是:用户名@认证域,例如:zhangsan@https,具体认证域名称是在服务端配置, sdk携带域名需要与服务端配置保持一致(具体认证域名称找服务端管理员提供)
- LDAP认证或者Radius账号认证场景, 密码字段正常传入LDAP用户密码或者Radius用户口令, 会由SDK透传到aTrust服务端, 再通过aTrust服务端会透传到对应的LDAP或者Radius认证服务器
- HTTP(S)账号认证通常结合APP服务器或者统一认证服务器进行单点登陆认证,其中的密码参数为HTTP(S)认证服务器需要的参数,不局限于密码,通常以json格式传递(具体格式需要管理员根据实际HTTP(S)服务器要求在服务端配置), SDK只是透传数据, 不做任何解析动作, 最终如何和第三方服务器对接是由aTrust服务端配置决定的, 可以让深信服交付工程师协助在服务端进行配置
NSURL *url = [NSURL URLWithString:@"https://10.242.1.24"];
/**
*用户名@认证域,具体认证域根据服务端配置来, 如果是LOCAL(账号认证)则不需要写@认证域, 格式为String userName = "xxxx", 下面是以HTTP(S)账号认证为例
*/
NSString *username = @"xxxx@https";//用户名@认证域
/**
* 密码字段, 如果是LOCAL(账号认证)直接传入密码, 如果是HTTP(S)账号认证传递单个信息可以直接放到密码字段直接传递,如果传递多个字段,建议使用json格式(也可以不是json格式,只是示例,可以随意自定义格式)sdk把整个 userName 和 password 当作字符串透传到服务端,服务端再去解析具体的值,或者直接传递第三方认证服务端对接
*/
NSString *password;
/**
* 开始用户名密码认证,认证结果会在认证回调onAuthSuccess,onAuthFailed,onAuthProcess中返回
*/
[[SFUemSDK sharedInstance] startPasswordAuth:url userName:username password:password];
服务器拿到password中的json数据会解析重组为第三方服务器所需的数据结构(服务端配置),然后代理访问第三方服务器,第三方服务器返回的信息会通过SDK的认证回调机制(onAuthSuccess)透传给用户侧,信息会保存在SFBaseMessage中的serverInfo中;
4、认证成功
主认证成功后,如果管理员未配置二次认证,就会执行onAuthSuccess回调,至此整个认证流程就结束了,认证成功后,应用就可以正常的访问aTrust管理员配置的内网服务器资源, 执行业务代码
示例代码如下:
/**
* 认证成功的回调
* @param msg 认证成功的信息
*/
- (void)onAuthSuccess:(BaseMessage *)msg {
//认证成功的业务
}
5、认证失败
如果有认证失败的情况,会执行onAuthFailed回调, 在该回调中提示用户,重新开始认证
示例代码如下:
/**
* 认证失败的回调
*
* @param msg 错误信息
*/
- (void)onAuthFailed:(BaseMessage *)msg {
// 重新开始认证或者其他逻辑
}
6、处理下一次认证
如果服务端配置了首次登陆强制修改密码,或者其他二次认证时,主认证成功后会回调此方法, 如果明确不需要适配二次认证, 建议在此回调给用户提示,让管理员调整配置
示例代码如下:
/**
* 主认证成功,但需要辅助认证(下一步认证)
*
* @param nextAuthType 下一步认证类型
* @param msg 下一步认证信息
*/
- (void)onAuthProcess:(SFAuthType)nextAuthType message:(BaseMessage *)msg {
NSLog(@"BasicSceneViewController onAuthProcess:%ld, msg:%@", (long)nextAuthType, msg.errStr);
/**
* 服务端配置了首次登陆强制修改密码,或者其他二次认证时,认证时会回调此方法,
* 此时如果不打算适配二次认证,建议给用户提示,让管理员调整配置
*/
[AlertUtil showAlert:[NSString stringWithFormat:@"暂不支持此种认证类型(%ld)", (long)nextAuthType] message:@"管理员请关掉此认证"];
}
7、监听注销回调
sdk使用过程中有可能出现被注销的情况,如应用主动调用注销接口、服务端管理员主动让用户下线等,所以应用监听注销回调是必须的,避免出现sdk内部已经注销了,但是应用无感知,从而出现业务异常的问题; 注意:注销回调建议在应用全生命周期内进行监听,避免出现在某个页面监听,页面销毁后,注销事件丢失的问题,可以参考MainApp中AppDelegate的处理方法:在sdk初始化后就用一个单例对象注册注销回调
示例代码如下:
/**
* 注册注销事件监听回调,推荐在AppDelegate里面监听,可以做到全局监听,方便统一处理注销事件
*/
[[SFUemSDK sharedInstance] registerLogoutDelegate:self];
8、免密认证
sdk提供了免密认证的能力,即认证流程全部成功后,重启应用或者服务端超时注销用户后,应用不需要再次使用用户名密码进行认证,可以直接调用免密认证接口进行认证上线
注意:
- 免密认证接口只需要在应用进程启动后调用一次, 进程未退出不需要再次调用
- 免密认证不能完全取代主认证,因为用户主动注销或者管理员在控制台主动让用户下线等场景下,免密信息会失效,免密认证就会失败,所以应用需要在免密认证失败后,继续使用用户名密码进行认证,可以参考SDKDemo中的处理方式
- 免密接口返回true, 仅表示当前本地状态是支持免密状态, 真正发送免密网络请求是在接口返回之后进行的; 但应用不必担心存在时序问题, 只要免密接口返回true, 就表示可以发起资源访问了, 在内部免密请求未真正成功前, 内部会缓存应用层的资源网络请求, 等内部免密成功后会立刻代理之前缓存的请求, 如果由于网络问题导致免密失败了, 内部会不断重试直到成功(重试间隔为3s一次), 应用不必关注内部免密机制, 只要网络恢复, 内部自然能免密成功并在成功后代理已缓存和新发起的资源请求.
- 因为免密接口返回true, 不表示内部已经真正免密成功, 所以存在一种场景: 在应用进程退出期间, 用户被注销了, 此时重新打开应用, 调用免密会返回true, 但内部真正发送免密请求时, 由于用户已经注销, 此时应用会收到注销回调. 这种场景是正常的, 只要确保在调用免密前已经注册注销回调监听, 收到注销后, 就按正常注销处理逻辑,引导用户重新登录
示例代码如下:
/**
* 这里是自动免密认证接口,返回true表示认证成功,此时用户就可以进行资源访问了,
* 如果返回false,表示当前不满足自动免密条件,需要用户主动调用用户名密码认证接口
*/
if ([[SFUemSDK sharedInstance] startAutoTicket]) {
[AlertUtil showAlert:@"免密认证成功" message:@"可直接跳到您的业务界面访问资源" completion:^{
[self showTestList];
}];
}
9、集成后关键流程自检
SDK文档中基于用户侧集成最容易出现问题的点, 提供了关键流程自测用例, 自测用例自测通过后, 可以确保集成无基本问题了.