单点登录方案选型


做了很多年的系统集成,其实方案大致就这么几种。

一、概念

单点登录(SSO),其实就像字面意思,A登录之后,与A相关的所有系统都不需要再次登录,百度你登录之后,百度地图、百度新闻、百度贴吧等等很多,都不需要再次登录,就是这个目的。

二、分类

按照类别的话,我把他们分成基于cookie,基于服务器通讯两种。

2.1 基于cookie类的,传统的都是基于cookie的,有要求限制主域名相同的,也有做服务器互信,然后单独解析的。

一般情况下,就是系统A认证过后,会在浏览器的cookie中存入相关的值,然后访问B的时候,将cookie中的值告诉B,B通过解析cookie,来判断是否登录成功,以及登录的人是谁,这个过程也有可能是通过与系统A或者单独的认证系统之间走通讯去识别,http类接口或者webservice类接口均有可能,看厂商的要求。

这种其实也不是很安全,我试过qq邮箱,其实就是基于cookie的,具体是哪个key值我忘记了,你让小A在北京登录A的qq邮箱,然后找到cookie中的key值,小B在沈阳打开qq邮箱,不登录,手动修改cookie中的key值,改成小A的,刷新页面。惊喜来了,你会发现登录的人变成了小A。

这种模式有一个比较严重的问题就是,cookie每次都需要验证,验证有效性之类的,多多少少对服务器的压力还是有一些大的,但是也可以通过代码识别sesion状态,判断是否验证,那样又会引发出会话已执行的问题,还得确定新的会话失效方案,稍微有点麻烦。

2.2 基于服务器通讯类,这种不依赖与cookie中的值,就是靠服务器之间自定义token认证传输

这种是我比较推荐使用的,个人觉得这种安全性高一点,而且对服务器的压力会小一些。

系统之间通过一些指定的加密方式和协议接口,进行消息传递,互相告知会话情况,登录和登出均采用消息传递模式,减少每次认证对服务器之间的压力。

三、举例

第一种,很传统的CAS集成。

很多公司目前也在用,很重,东西很多,而且个人觉得毛病也不少,需要部署CAS服务器,而且认证需要三次的重定向,还是基于浏览器cookie,每次退出都很捉急。

CAS经常会出现一种问题就是偶发性的ticket失效,访问页面403、超时均有可能,我接触过很多公司,但是都没有这个的解决方案,总结基本上都是网络问题、负载问题等,其实还是源码展示的信息不够完整。

百度找的图片,还挺靠谱

第二种,就是轻量级的Oauth2集成。

这种是现在比较主流的集成方案,三次握手机制,核心思想就是第一次的请求是基于浏览器的http请求,由此来确定相关登录人员。服务器之间通过颁发的code和secret进行token认证,token时效性,加密型都要有考量。

这个图是我简单画的

第三种,各个厂商自己做的jar包

有一些可能会要求配置拦截器和监听器,有一些可能jar包只是用来做加密处理,需要客户端进行引用。

其实都是大同小异,个人不推荐部署其他厂商jar包,因为涉及到引用的相关jdk版本,以及包名冲突,更重要的是分支维护起来比较麻烦。

SSO