近日研究了Sina CAS的登陆过程,发现其实sina的sso实现了yale-CAS并且添加一丁点新的东西,基本认证过程交互流程仍然未变。其独创的一点是实现了Ajax单点登陆,算是比较牛。实现原理是iframe+ javaScript回调函数。
一,初级SSO
初级的SSO,就是在同一个顶级域名下,通过种入顶级域名的Cookie,来实现统一登陆。例如:
单点登陆地址:sso.xxx.com/login.jsp
应用1: web1.xxx.com/login.jsp
应用2: web2.xxx.com/login.jsp
应用3: web3.xxx.com/login.jsp
登陆流程:
情况一:(用户从未登陆)
1, 用户访问web1.xxx.com/login.jsp,web1重定向到sso.xxx.com/login.jsp
2, 用户输入验证,成功。sso.xxx.com种入.xxx.com域Cookie的tokenid,重定向到web1.xxx.com/login.jsp,web1.xxx.com访问.xxx.com域Cookie的tokenid判断出已经登陆,系统登陆完成。
情况二:(用户已经登陆)直接登陆。
二,Sina SSO
Sina实现了跨域名的统一登陆,本质也是基于Cookie的。如果用户禁用Cookie,那么无论如何也是登陆不了的。例如:Sina SSO服务器是login.sina.com.cn/sso/login.php
,微博登陆地址为weibo.com/login.php。通过回调函数和iframe实现了跨一级域名的登陆。
认证过程具体流程:这里只介绍用户从未登陆过。
1, 用户进入weibo.com/login.php
2, 用户输入用户名称。输入完毕后,当用户名输入框焦点失去的时候,页码通过ajax向服务器login.sina.com.cn/sso/prelogin.php发送请求,参数为user(刚刚输入的用户名)。服务返回server time 和nonce 认证,通过回调函数写入到javascript变量中。
3, 用户输入密码,点击登陆,页面POST 请求(注意是ajax请求,并不是login.php发送的),
login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.12),请求的发起的页面是weibo.com/login.php中的一个不可见iframe页面,参数为第二步得到的servertime和nonce ,已经用户名称和加密的密码。返回种入Cookie tgt在login.sina.com.cn下。同时修改iframe地址为weibo.com/ajaxlogin.php?ticket=XXXXXX,注意ticket非常重要,这是用户登陆和服务的凭证。
4, iframe 访问weibo.com/ajaxlogin.php?ticket=XXXXXX,用户登陆,返回种入cookie在.weibo.com下,记录用户登陆信息。
5, 通过js再次访问weibo.com/login.php,因为cookie已经写入,登陆成功,服务器发送302,重定向到用户主页面。Weibo.com/userid。
6, 至此,登陆过程完成。
重点:交互过程和密码加密算法分析。
1, 在提交POST请求之前, 需要GET 获取两个参数。
地址是:http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.18)
得到的数据中有 "servertime" 和 "nonce" 的值, 是随机的,其他值貌似没什么用。
2, 通过httpfox 观察POST 的数据, 参数较复杂,其中 “su" 是加密后的username, "sp"是加密后的password。"servertime" 和 ”nonce" 是上一步得到的。其他参数是不变的。
username 经过了BASE64 计算: username = base64.encodestring( urllib.quote(username) )[:-1];
password 经过了三次SHA1 加密, 且其中加入了 servertime 和 nonce 的值来干扰。
即: 两次SHA1加密后, 将结果加上 servertime 和 nonce 的值, 再SHA1 算一次。
将参数组织好, POST请求。