7.12 ProviderLogin
Limax框架中,Provider为应用提供服务。某些应用场景,存在Endpoint切换Provider的需求,从源Provider携带特定的Session数据,传送到目的Provider,本质就是Session迁移。使用ProviderLogin机制,源Session数据在目的Provider创建Session之前安全传送到目的Provider,可以大大简化Session迁移类应用的开发。
-
7.12.1 基本原理
-
流程考虑
通常的登录流程为
1. Endpoint连接Switcher,发起登录请求,登录请求包含所有需要访问的Provider。
2. Switcher向Auany转发登录请求。
3. Switcher获得Auany的授权之后,向请求的所有Provider发起上线通告。
4. 收到上线通告的Provider,成功初始化Session之后,向Switcher发出OK应答。
5. Switcher收集Provider发来的应答,如果全部OK,向Endpoint发送上线通告。
ProviderLogin机制扩展了登录流程的第3步。Switcher获得Auany的授权之后,逐一判断请求的Provider是否需要LoginData,如果需要,向Endpoint查询LoginData,接下来向Provider发起上线通告,附带LoginData。
-
安全考虑
存在两种形式的LoginData,安全的和不安全的。
1. 来自同一信任域的Provider发送的隧道数据可以用来创建安全LoginData,包含了label与data,详见《Provider间数据交换》。
2. 应用使用其它方式指定的数据只能创建不安全的LoginData。
-
-
7.12.2 服务器开发
Provider实现limax.provider.ProviderListener时,并列实现limax.provider.LoginDataSupport接口。
public interface LoginDataSupport { }
LoginData接口仅为一标签接口,不需要实现任何方法。实现该接口的Provider连接Switcher时,将报告Switcher,该Provider需要LoginData。
ProviderListener.onTransportAdded方法的实现代码中,可从Transport中获取LoginData。
@Override public void onTransportAdded(Transport transport) throws Exception { ProviderTransport pt = (ProviderTransport) transport; LoginData loginData = pt.getLoginData(); String message; if (loginData != null) { if (loginData.isSafe()) message = "SAFE LoginData " + loginData.getLabel() + " " + Helper.toHexString(loginData.getData().getBytes()); else message = "UNSAFE LoginData " + Helper.toHexString(loginData.getData().getBytes()); } else message = "NO LoginData"; System.out.println(message); }
这里可以看到,如果Provider需要LoginData,客户端没有提供,那么返回的loginData为null,是否作为错误,应用自己决定,抛出异常即可关闭客户端的网络连接。需要注意,onTransportAdded之后,Transport上存储的LoginData即被清除,这是考虑到LoginData数据量可能较大,如果应用忘记清除,浪费内存空间。
-
7.12.3 客户端开发
-
HTML5之外的所有客户端
使用limax.endpoint.ProviderLoginDataManager组织LoginData,提供3个add方法。
void add(int pvid, Octets unsafedata); void add(int pvid, int label, Octets data); void add(int pvid, int label, String data);
其中,不使用label的方法,表明提供的是不安全LoginData,带String参数的add方法用于构造LoginData的隧道数据来自脚本系统的情况。
如果期望使用字符串作为不安全LoginData,可以编码成UTF8格式的Octets再add,同时服务器端使用UTF8解码,有助于获得最好的兼容性。
LoginConfig中选用带ProviderLoginDataManager参数的静态方法,创建登录信息。
-
HTML5客户端
按照如下模式定义login参数对象
var login = { scheme : 'ws', host : '127.0.0.1:10001', username : 'testabc', token : '123456', platflag : 'test', pvids : [100], logindatas : { 100 : { data : 'unsafedata' }, 101 : { label : 0, data : <base64tunneldatastring> } } } var connector = WebSocketConnector(limax, login);
-