1. 概述
单点登录是指用户在其中一个系统登录之后,用户再漫游至其他相关系统时,不需要重复的登录。真正使用户感觉到“一点登录、全网通行”。
目前比较流行的COOKIE认证的方式。其实现示意图如下:
统一验证由用户首次登陆Web页面时向用户浏览器写一个包含用户账号,用户Token的Cookie信息。并且由应用服务器取得这个信息以后提交到验证服务器数据库中进行注册判断。
如果用户信息注册成功,则在应用服务器上面以Session形式记录下此用户己经正确登陆的信息,以后用户再次登录些应用服务器的时候只要对此Session信息进行判断,如果Session信息存在并且是表示用户正确登陆,则用户通过验证,不需要第二次输入用户名和密码。若Session信息消失,则应用服务器提取用户浏览器中的Cookie信息再次到验证服务器上进行验证,通过验证以后再次在应用服务器端用Session信息将用户信息保存。
如果用户在应用服务器端跳转的话,每跳转到一个新的应用服务器,则应用服务器必须取得用户浏览器端的Cookie信息到验证服务器上进行一次验证,验证通过以后则同样注,Session信息在应用服务器上,以完成对用户验证的通过。
单点认证由用户首次登陆Web页面时向用户浏览器写内存Cookie,目前暂定为(userToken、loginId),同时,为了保证Cookie访问的安全性,需要把Cookie的domain设成统一的domain,只有在访问同一domain的网站才能获取该Cookie。
注:Cookie信息可以根据应用的需要,增加一些公共的字段值,以显示给用户。
3.1. 统一登录流程
验证流程如下:
(1)
当用户首次通过Web登陆时,由Web端计算token值(参见第三方接口实现),并写入以上Cookie信息到浏览器中及以Session形式记录下此用户己经正确登陆的信息
(2)
对于任何一台Web服务器,都是通过以下方法来验证用户身份:
a)
判断Session是否存在,如果存在,则认为验证通过。则b)
b)
如果Session不存在:
I.
判断Cookie信息是否存在,如果都不存在,则(c)
II.
如果Cookie信息存在,则读取Cookie值,根据Cookie值loginId查询中心数据库中对应的密码,并计算userToken的Token值,比较算出的Token值和取出的值是否相等,如果相等则写loginId和userToken的Session值,并让用户通过。否则(c)
c)
转到登录页,让用户输入用户名、密码进行验证,验证通过后,写userToken和loginId的Session值及userToken和loginId的Cookie值。
用户退出登录时,把userToken和loginId的Session值及userToken和loginId的Cookie值清空。
4. 安全性分析
用户的帐号和密码以md5加密的形式保存在Cookie中,而且加入了key,用户难以破解。即便用户可以破解出Cookie值,也只能够根据userName来穷举用户密码和key,而且还要进行加密运算,难度很大,代价昂贵;
用户不可能伪造token值,因为token为加密运算(MD5加密产生32位的数);
用户把浏览器关掉以后,Cookie自动失效,并且是以非文本形式存在,这一点来讲也是比较安全。
登陆信息的传递都是通过Cookie以密文的方式,拦截几乎无可能。
5. 第三方接口实现
5.1. 统一认证接口
统一认证平台提供统一认证的WebService接口服务,具体如下说明:
该WebService需要客户端的API 鉴权,访问WebService时请添加用户名和密码。用户名:cnlife 密码:cnlife#^%365
l
认证接口
User authenticate(String loginId, String password);
认证通过,返回一个User对象,否则返回null。
l
查询基本信息接口
User getUserBaseInfoByLoginId(String loginId);
根据用户的登陆帐号,获取用户的基本信息。查询成功,返回一个User对象,否则返回null。
返回的User是标准的Java Bean。定义如下:
User(userId,loginId,password,msisdn,nickName,email,gender)
;
用户ID userId String
登陆帐号 loginId String
登陆密码 password String
手机号码 msisdn String
昵称 nickName String
电子邮件 email String
性别 gender String(1为男,0为女)
5.2. 登陆认证流程说明
验证过程说明:用户首次通过Web登陆时,根据登陆帐号和密码在统一平台进行认证,认证通过可获取用户的基本信息。
认证通过后,为了满足SSO的“单点登陆,全网通行”,需要进行一系列的处理,具体过程如下:
1、
计算token
2、
将loginId和计算出来的tokern置入cookie
//
将
token
和
loginId
设置入
cookie .
Cookie aCookie;
// token
aCookie = new Cookie(“cnlifeUserToken”, userToken);
aCookie.setMaxAge(-1);
aCookie.setDomain(“hyit.edu.cn”);
aCookie.setPath("/");
response.addCookie(aCookie);
loginId = new String(loginId.getBytes("GBK"), "ISO8859_1");
aCookie = new Cookie(“cnlifeUserId”, URLEncoder.encode(loginId, "iso-8859-1"));
aCookie.setMaxAge(-1);
aCookie.setDomain(“cnlife365.com”);
aCookie.setPath("/");
response.addCookie(aCookie);
完成登陆认证。
注:如果是JAVA技术实现的系统,我们将提供API协助完成该操作。
5.3. 漫游登陆流程说明
当用户从A系统漫游到B系统时,B系统需要做以下操作:
1
、判断用户在B系统是否存在Session信息,如果存在,用户处于登陆状态,无需再进行以下操作。
2
、判断对应的Cookie是否存在
Cookie[] userCookie = request.getCookies();
if (userCookie != null)
{
int cookieLen = userCookie.length;
for (int i = 0; i < cookieLen; i++)
{
String cookieKey = userCookie[i].getName();
mLogger.info("Cookie Key : " + cookieKey);
if (cookieKey != null && cookieKey.equalsIgnoreCase(“cnlifeUserToken”))
{
cnlifeUserToken = userCookie[i].getValue();
}
if (cookieKey != null && cookieKey.equalsIgnoreCase(“cnlifeUserId”))
{
cnlifeLoginid = URLDecoder.decode(userCookie[i].getValue().toString(), "iso-8859-1");
}
}
}
cnlifeLoginid = new String(cnlifeLoginid.getBytes("ISO8859_1"), "GBK");
3
、如果Cookie不存在,直接到登陆页面
4
、如果Cookie存在,使用Cookie中的登陆帐号,到统一认证平台获取用户的基本信息。根据加密规则对用户的基本信息进行计算,获得Token。对这个Token和Cookie中的Token进行比较,如果符合,用户登陆成功。
5.4. 用户退出登陆
用户退出登陆的时候,除了清除本系统的相关Session信息,还需要对相关Cookie进行清除。
Cookie aCookie;
aCookie = new Cookie(“cnlifeUserToken”, "");
aCookie.setMaxAge(-1);
aCookie.setDomain(“hyit.edu.cn”);
aCookie.setPath("/");
response.addCookie(aCookie);
aCookie = new Cookie(“cnlifeUserId” "");
aCookie.setMaxAge(-1);
aCookie.setDomain(“hyit.edu.cn”);
aCookie.setPath("/");
response.addCookie(aCookie);