单点登录(SSO)总结
背景
准备搭建一个无线平台, 对公司内部资源进行管理. 平台包括几个系统, 分别管理资源\销售数据\下发记录等等. 其中权限部分要和单点登录结合. 同事A评估说CAS只是单点, 无法满足现有权限整合, 发现我这边有一个半吊子权限管理系统. 于是领导要求移植并改写.
遇到问题
多台服务器间登录信息(目前存在session中)的共享问题. 其实还是一个单点问题, 没开始做的时候想的好简单啊. 最后几乎活生生的写了个简陋的单点… 想来可能改 CAS + SpringSecurity 更为简单, 可惜方案一开始就给否了. 记一下解决方法吧.
单点登录
SSO英文全称Single Sign On, 单点登录. SSO是在多个应用系统中, 用户只需要登录一次就可以访问所有相互信任的应用系统. 它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制.
流程如下图
(无视掉我的烂字吧…电脑里没装画图软件就世界上手了…)
-
用户访问A平台, session中无用户信息, 转至 SSO server
-
SSO Server 进行登录验证, 返回ticket, 本地add cookie
-
通过callback URL 返回A平台, 在A平台对ticket的有效性进行判断, 成功则把登录信息放进session中保存…
-
当访问B平台时, 转至SSO server, 读cookie, 返回ticket
-
返回B平台对ticket的有效性进行判断, 成功则把登录信息放入session中保存…
PS: SSO server端采用memcached进行对登陆信息的存储(可以是数据表什么的,采用memcached是因为有效期,不用手动管理了)
主要解决的问题
a. cookie的跨域读取问题
b. 登录信息的获取以及保存
c. ticket的生成以及校验
a.cookie的跨域读取
cookie不能跨域访问, 因此每个平台过滤发现不符合权限条件的用户应该是跳转到SSO Server. 应注意设置cookie的路径为根目录.
cookie.setPath("/"); //设置cookie的作用路径
b. 登录信息的获取以及保存
第一次登陆时, 生成一个随机加密的串作为tokenKey,加到本地cookie同时储存到服务器memcached里,value是登陆信息. 当第二次访问平台B … 平台N时, SSO server首先读取本地cookie, 取到tokenKey, 再去memcached里拿回登陆信息并加密,返回登陆信息和ticket.
c. ticket的生成以及校验
ticket现在的传送方式是明文get发到callback地址,因此需要考虑时效性和安全性问题. 现在采用的方式是 md5(时间戳 + 用户信息 + 公钥). 然后在各平台进行ticket的比较校验. 时间戳在30分钟内有效. 现在还没想到更好的ticket生成和校验方法, 应该多学习.
单点注销:
这个现在只能是每个平台自己注销session, 然后跳转至SSO server注销Cookie.
Cookie cookie = new Cookie("name",null);
cookie.setMaxAge(1);
response.addCookie(cookie);
以上是注销cookie, 要注意的是setMaxAge这个属性, 网上很多人说设置0, 实际上要设置1才会失效.