新近一家公司上来就让作oa,要求嵌入公司现有系统模块,天然而然想到模拟post单点登陆对方系统新建单点登录页面保存session,然现有系统都有用cookie保存用户信息,故保存本地cookie……测试失败。网上查询得知,生成的cookie所在的domainName不一样所致,也就是存在cookie跨域访问问题。javascript
由于现有相同都是ip+端口访问方式,故没法使用二级域名共享cookie,现想到方法就是利用iframe来实现SSO,解决方法以下:java
主系统经过js建立隐藏iframe(src路径即为子系统所建ashx页面)redis
//建立隐藏iframe调用单点登陆页面实现cookie跨域共享 var sso_frm = document.createElement("iframe"); sso_frm.style.display = "none"; sso_frm.src = "@ViewBag.SSO_Url?uid=@ViewBag.uid&pwd=@ViewBag.pwd"; document.body.appendChild(sso_frm);
子系统新建一个ashx页面,接收参数并写入cookie (代码略),这个方法取了个巧,至关于变相的登陆了其余系统,惟一不足之处就是在主平台登陆时须要遍历全部权限内子系统建立iframe并登陆,这个方法能够很好地处理不一样主域下的单点登陆。跨域
扩展:缓存
1)对于相同主域下的二级域名咱们能够利用二级域名共享cookie实现单点登陆如:站点A登陆后建立cookie,设置主域:cookie.Domain = "sso.com",此时B登陆可直接获取A建立的cookie。cookie
2)对于不一样主域下的单点登陆除了利用iframe还能够借助统一认证站点(passport.com)来实现单点登陆session
例如”app
站点A www.a.comdom
站点B www.b.compost
认证站点C www.passport.com
票据:ticket加密的帐号密码以cookie形式存在。
认证过程:假设用户user1不曾登陆过站点AB, A登陆后判断 a_ticket(user1加密帐号密码)是否存在,不然跳转站点C验证页面,登陆成功后生成c_ticket(加密帐号密码)并返回A站a_ticket;然后B站点登陆会重定向站点C 验证c_ticket验证成功返回b_ticket并重定向B。
3) 咱们也能够利用redis来替换认证站点C 处理逻辑与上述过程相似:
1.user1访问站点A,若是a_ticket存在则正常登陆,不然判断缓存中是否存在以user1帐号为key的值(user1帐号密码加密),若是存在即返回该值并写入a_ticket,若是不存在即跳转站点A登陆页登陆后建立user1的redis缓存并建立a_ticket;
2.user1访问站点B,若是b_ticket存在则正常登陆,不然判断缓存中是否存在以user1帐号为key的值(user1帐号密码加密),若是存在即返回该值并写入b_ticket,若是不存在则挑战站点B登陆页面登陆后建立
user1的redis缓存并建立b_ticket;
总结:写的有点碎,可是大致意思应该表达清楚了,实现起来也比较简单就再也不赘述。