单点登录
一、单点登陆分两种
1.1子域单点登陆/二级域单点登陆
例如:site1.domain.com和site2.domain.com相同域之间单点登陆
子域单点登陆实现比较简单。利用cookie就行
1.2完全跨域单点登陆
例如:www.baidu.com和www.jd.com不同域之间单点登陆。
跨域单点登陆实现要借助认证中心(www.passport.com)。由于不同域之间cookie不能访问。如果全部登陆认证退出操作都在认证中心完成,那这样浏览器和认证中心就形成一对一关系。跨域问题也就解决了。
二、跨域单点登陆步骤
认证系统(www.passport.com)根据用户在浏览器中输入的登录信息,进行身份认证,如果认证通过,返回给浏览器一个证明[认证系统_ticket]。由于[认证系统_ticket]是由认证系统产生存放在浏览器的cookie,cookie不能跨域访问所以读取cookie只有认证中心系统能读取。
当用户访问www.site1.com首先判断业务系统是否有登陆,判断是否已经登陆依据ticket[业务系统_ticket]。由于没有登陆被重定向到www.passport.com,认证中心会获取浏览器带[认证系统_ticket]的cookie,然后进行验证通过则跳转到请求页面。然后在www.site1.com业务系统生成session或者www.site1.com业务系统ticket[业务系统自己本身的ticket],当用户再次访问www.site1.com时就不需要远程认证,直接在www.site1.com业务系统认证自己cookie里面的ticket[业务系统1_ticket]或者判断session是否为空,验证通过就直接登陆。
当用户访问www.site2.com首先判断业务系统是否有登陆,判断是否已经登陆依据ticket[业务系统_ticket]。由于没有登陆被重定向到www.passport.com,认证中心会获取浏览器带[认证系统_ticket]的cookie,然后进行验证通过则跳转到请求页面。然后在www.site2.com业务系统生成session或者www.site2.com业务系统ticket[业务系统自己本身的ticket],当用户再次访问www.site2.com时就不需要远程认证,直接在www.site2.com业务系统认证自己cookie里面的ticket[业务系统2_ticket]或者判断session是否为空,验证通过就直接登陆。
其它业务系统加入跨域单点登录过程跟上面的一样。
三、共享session数据方式实现跨域单点登录
3.1、首次登录成功将session数据保存在redis服务器,将ticket[认证系统_ticket]保存到浏览器。
3.2、访问另外服务器发现没登录没ticket[业务系统_ticket],将链接重定向到验证中心(redis服务器)时带上ticket[认证系统_ticket],验证ticket[认证系统_ticket]。
3.3、每个域第一次经过验证中心验证后,都会向浏览器写对应的[业务系统_ticket]。
3.4、理解 [认证系统_ticket] 和 [业务系统_ticket] 区别。
小结:
首先读取业务系统ticket[本身业务系统ticket]或者session,然后进行本地认证。如果没有将重定向到认证系统(www.passport.com),由认证系统读取之前是否产生过ticket[认证系统_ticket]。如果有则让业务系统登陆同时让它生成自己的业务系统ticket或者session。
[认证系统_ticket]和[业务系统_ticket]也可以是一样。每次业务系统认证都带上[业务系统_ticket]到认证中心认证然后跳转回来。
2.2、完成一个简单的SSO单点登录的功能,需要两个部分的合作
统一的身份认证服务中心 -> 一个认证服务类
认证服务中心产生认证中心ticket,每个业务系统第一次登陆都要进行一次远程认证。认证通过则在业务系统生成业务系统ticket。
业务系统对每个访问进行拦截检查ticket。业务系统产生业务系统ticket或者session进行本地认证,免除远程验证带来的开销。
2.3步骤解析
认证服务中心负责生产[认证ticket]、验证[认证ticket]、销毁[认证ticket]。
业务系统通过过滤器拦截对每个请求进行拦截检查。判断系统是否已经登录或者是否其它业务系统进行过单点登录。
判断系统是否已经登录:通过session是否为空 UserSession session = session.getAttribute("USERSESSION"); 不为空代表已经登陆过。
判断其它业务系统进行过单点登录:通过检查[认证ticket]是否为空,重定向到认证中心校验[认证ticket]是否正确。
如果用到session判断业务系统它们都有自己一套登陆入口程序。当然所有业务系统整合仅仅用单点登录为登陆入口程序也行。
ticket是单点登录凭证,保存在全局cookie提供给个业务系统读取。
三、总结
3.1cookie是单点登录的突破点
3.2cookie[ticket]分两类:认证中心系统cookie[认证系统_ticket]和业务系统cookie[业务系统_ticket]。
3.3认证中心生成验证销毁[认证ticket]是最常用,每个业务系统都要远程访问一次。然后生成自己ticket[业务ticket]或者session之后就不用在登陆了。
3.4每个业务系统各自生成验证销毁[业务ticket]避免提交远程验证的开销。缺点[业务ticket]生成验证销毁代码在各业务系统重复。
3.5当然子域单点登陆也可以用跨域单点登录方式利用认证中心处理。
四、以往对单点登录理解
第一种方案客户端带ticket访问位于不同服务器上业务系统,然后由业务系统把客户传过来的ticket交由远程认证服务器进行认证。ticket生成后保存在认证系统,同时发送给客户端浏览器以cookie形式保存。ticket生成验证销毁都在认证服务器完成。当客户端请求别的业务系统就会带ticket,业务系统发现请求有带ticket就会转发给远程认证中心系统进行认证。
第二种方案客户端ticket不需要发送到远程的认证中心,ticket生产验证销毁的功能集成在每个业务服务器上。但ticket生产验证销毁规则必须是一致的。只有规则一致才能保证客户端带ticket的请求在每个业务系统验证通过。
五、单点登录token作用
5.1、token可以是任意值
常见token值:UUID、md5(随机值+用户信息)
5.2、token类比游乐园门票
token可以比喻为游乐园门票。当购票人购买了门票,售票人员就登记此票可以到A、B、C园区玩。只要到园区门口给验票员校验一下门票就可以了。
5.3、系统单点登录token
游乐园门票使用场景与系统单点登录token使用场景非常相似。
当用户访问A访问器会先到验证中心验证身份合法性(相当于购票中心买票)。
验证通过会返回用户token,并且记录token可以免密登录那些服务器, (相当于门票可以游玩那些园区)。
下面用josn格式表示token可以免密登录那些服务器:
{"token" : ["服务器A","服务器B","服务器C"]}
6、单点登录待解决问题?
6.1、认证中心系统怎样返回token给各个业务应用系统?
6.2、各个业务应用系统怎样验证token?
感谢您的阅读,您的支持是我写博客动力。