请参见上一篇文章,登录MSN协议
具体Java实现:
命令序列:<<代表发送,>>代表结果
1.连接DS(Dispatcher Server),得到NS(Notification Server)
<<VER 1 MSNP18 CVR0
>>VER 1 MSNP18
<<CVR 2 0x0804 winnt 5.1 i386 MSNMSGR 14.0.8089.0726 msmsgs yourAccount
>>CVR 2 14.0.8089 14.0.8089 14.0.8089 http://msgruser.dlservice.microsoft.com/download/0/9/7/0974F7CD-D082-46FE-922D-806670345793/zh-chs/wlsetup-cvr.exe http://download.live.com/?sku=messenger
<<USR 3 SSO I yourAccount
>>XFR 3 NS 207.46.124.86:1863 U D
这里有一个类叫NonBlockTelnetClient是为了向服务器发送命令用的类(这只是一个简单的示例,未考虑更多其他问题)
2.通过第一步,可以得到NS的IP地址了,接着进行登录
<<VER 4 MSNP18 CVR0
>>VER 4 MSNP18
<<CVR 5 0x0804 winnt 5.1 i386 MSNMSGR 14.0.8089.0726 msmsgs yourAccount
>>CVR 5 14.0.8089 14.0.8089 14.0.8089 http://msgruser.dlservice.microsoft.com/download/0/9/7/0974F7CD-D082-46FE-922D-806670345793/zh-chs/wlsetup-cvr.exe http://download.live.com/?sku=messenger
<<USR 6 SSO I yourAccount
>>GCF 0 4804
<Policies>...</Policies>USR 6 SSO S MBI_KEY_OLD cfznpPIvKOe2GlNv6z3OleqF8lrlNas2MM+fpobPjNLy2LZAeWQb6wcrcbMomSyn
以下这段代码完成上述协议序列
接着得到policy和nonce
然后发送SOAP到https://login.live.com/RST.srf(soap格式:http://msnpiki.msnfanatic.com/index.php/MSNP15:SSO)
从结果的xml中(soap格式:http://msnpiki.msnfanatic.com/index.php/MSNP15:SSO)可以取到secret和ticket
对其进行编码得到ssoticket
以上过程的代码如下:
注意SOAP请求中,发送了RST0,RST1,RST2分别对应三个域http://Passport.NET/tb,messengerclear.live.com,contacts.msn.com,即从这三个域中得到相应的ticketToken,每个ticketToken分别用于不同的域(不能混用)。
跳过第一个<wst:BinarySecret>,得到第二个<wst:BinarySecret>中的内容为secret
得到<wsse:BinarySecurityToken Id="Compact1">中的ticket为ticket1,得到<wsse:BinarySecurityToken Id="Compact2">中的ticket为ticket2,CompactN对应于RSTN,因此Compact1对应于messengerclear.live.com(这个是用于msn验证的域)的ticket,而Compact2对应于contacts.msn.com的ticket,登录时只用ticket1,而ticket2被赋给ticketToken用于取联系人时的ticket
为什么要发送RST0呢,下面的链接文档中只说明了这个是登录必须的,但其返回的Compact0中的ticket是没用的
[协议中说:如果你的policy为MBI, MBI_SSL or MBI_KEY_OLD,则你的ticket为<wsse:BinarySecurityToken Id="Compactn">中的内容 ;如果你的policy包括一个以问号开始的串,则ticket为<wsse:BinarySecurityToken Id="PPTokenn"> 中的内容]
具体见:http://msnpiki.msnfanatic.com/index.php/MSNP15:SSO
HttpBrowser类,只是一个httpclient的封装,可以发送post和get请求
HttpResponse类,是http回复内容
以上两个类在此就不给出了
另外还有一个Base64Coder类,是进行base64编码的类
接着:利用上述返回的ticket进行登录
<<USR 7 SSO S ssoticket {691CC6CA-F23C-4E86-BB91-82965CBC5429}
>>USR 7 OK yourAccount 1 0 (登录成功)
以上便登录成功了