[转] SSO单点登陆原理和流程分析

WEB的登陆那些事####

说道帐户登陆和注册,其实咱们天天都在亲身感觉着,像微博、知乎还有简书等等。咱们老是须要按期的去从新登陆一下,对于这种认证机制,咱们都能说出来两个名词,Cookie、Session。的确没错,Cookie和Session是实现这一切的核心。前端

为何会有Cookie和Session?区别是什么?
引入这两个概念的根本缘由是由于Http协议是无状态的,也就是说它不能创建起屡次请求之间的关系。因此须要引入一个能有浏览器或服务器保存的一个上下文状态,也就是Cookie和Session。说到底Session的实现是依赖于Cookie的,由于Cookie是真正的由浏览器保存的状态,Session是利用了JSessionID。在我看来其实二者有差别,可是根本的依赖是同样的。Cookie也是有生命周期的,像Session级别或者有必定“寿命”的Cookie。一切是由浏览器去维护的。java

常见的跨域登陆问题####

以前楼主主要是作帐户和Passport这方面的工做,其实在跨域这也是遇见了一些问题。json

对于同一个根域下的登陆问题#####

若是咱们的站点有不止一个业务,那么他们可能部署在不一样的机器上,也每每须要不一样的域名进行区分。可是全部的业务又都是依赖于一套帐户体系,那么咱们这时候须要经过一次登陆解决全部站点的登陆问题,那么咱们这个时候可使用一个最笨的方法:那就是一次登陆成功,将Cookie写到根域下,那么这样全部的站点就能实现,同一个根域下的Cookie共享,天然实现了”单点登陆“。后端

对于多个根域下的登陆问题#####

若是是多个根域名,那么这种状况下上面的机制就不能实现“单点登陆”了。由于之因此上面能够实现“单点登陆”的效果。是由于浏览器和Http协议的支持。可是对于跨根域的站点之间进行Cookie的共享是比较复杂的。跨域

方法1:登陆成功以后将Cookie回写到多个域名下。浏览器

这种办法可能十分简单,你能够经过后端的response写,也能够用前端js去写,可是必须有对全部须要“单点登陆”的站点进行逐一的写入。用脚想这种办法也是行不通的,由于你须要维护一个站点的列表,维护工做十分复杂,同时对于增长站点也会特别痛苦。对于Cookie的销毁也是十分复杂的,由于仍是要对全部域名下的Cookie进行删除。也就是说将原来须要作的工做增长了n倍。对于小型站点这种办法是可取的。安全

方法2:jsonp服务器

搞过前端的可能都知道用jsonp能够作跨域的请求,而咱们解决的就是多个域下的统一登陆的问题,好像很瓜熟蒂落的样子。可是,登陆是Server端作的吧?咱们在Client端作跨域的处理,这怎么看也不是很合理。同时这种办法须要很大的维护成本,每一次请求都要去固定的域下取相应的Cookie以后再作请求。想一想维护有头疼。ide

方法3 :引入一个中间态的Serverjsonp

这种办法算是一个简化版的SSO,实现思想也十分的“狡猾”。可是对于小网站作跨域登陆的处理却十分的有用,具体思路以下:

首先,咱们有两个域名要实现单点登陆,同时咱们须要一个中间的Server。

  1. 咱们有一个系统域名为xulingbo.net,当咱们登陆的时候访问xulingbo.net/wp-login进行登陆,登陆成功以后将Cookie回写到xulingbo这个域名下。
  2. 咱们还有一个系统域名为javaWeb.com,当咱们访问inside-javaWeb的时候,咱们没有Cookie,那么请求跳转到中间系统jump。此时须要将当前域名带到参数中便于jump校验。这个jump系统是在xulingbo域下的即:jump.xulingbo.net。这时候就能拿到以前写在xulingbo域下的Cookie。
  3. jump系统在收到了xulingbo域下的Cookie以后,取出xulingbo域下的Cookie,并redirect请求jump.inside-javaWeb.net,这个接口也是在jump系统中,请求后jump系统将Cookie回写到inside-javaWeb域名下,这样就实现了简易的单点登陆。以下图所示:
 
Paste_Image.png

可是这种方式不是很灵活,对于数据传输的安全性没有保障,而且在销毁Cookie的时候无能为力,只能所有遍历的销毁。

方法4:基于CAS的SSO系统

CAS可不是java中的Compare-And-Swap,它是一个开源的单点登陆系统(SSO)。实现的机制不算复杂可是思想十分灵巧。用CAS也能够快速实现单点登陆。盗图一张说明sso单个域的登陆和验证流程:

 
Paste_Image.png

CAS主要分为CAS Client 和CAS Server ,其中Client主要是内嵌在须要SSO登陆站点的拦截器或过滤器上。

  1. 首先浏览器向站点1发起请求。
  2. 站点1发现当前请求没有合法的Cookie,那么重定向到CAS Server上,也就是SSO Server。
  3. CAS Server展现登陆界面,要求用户登陆。
  4. 用户登陆后,会写CAS Server的Cookie到浏览器,同时生产ticket,利用一个302跳转到CASClient。这样能保证用户无感知。
  5. CAS Client利用生成的ticket发送到CAS Server进行验证,验证经过后,站点1生成本身的Cookie并回写到用户浏览器,而后进行登陆成功的跳转。

这样就能保证当前浏览器在站点1的域名下,有站点1的Cookie,同时当前浏览器也有CAS Server的Cookie。

接下来看下站点2的登陆:

 
Paste_Image.png

站点2,在进行登陆时和站点1初次登陆流程一致,可是在访问CAS Server的时候,因为当前浏览器已经有了CAS Server的Cookie,那么直接校验经过返回ticket。
ticket经过302跳转跳转到CAS Client上,以后的流程就和站点1是同样的了。若是此时认证失败,那么须要从新走一次登陆的过程。

其实感受很麻烦,可是流程却十分的简单,主要是使用CAS Server的Cookie作校验,同时各自系统维护本身的Cookie。

注意的问题:

  1. CAS Server的Cookie劫持问题,若是CAS Server的Cookie被劫持掉,那么就至关于拿到了一切,因此必需要用HTTPS实现这个过程。
  2. ticket的使用,ticket只能被使用一次,一次校验后当即失效。同时须要有时效性,通常5分钟。最后ticket生成规则要随机,不能被碰撞出来。
  3. 对于各自系统本身的Session,也能够依赖于SSO,这样就能保证全部的Session规则一致,便于集中控制。

其实SSO的实现很灵活,CAS只是说了一个原理,至于具体怎么实现,须要平衡安全性、易用性等诸多因素,因此也没有一个固定的实现方案。

上面就是所有我知晓的SSO的实现了,由于以前一直在作相关的东西,这个过程当中也作了不少的挣扎和思考,整理出来,帮助全部正在作的童鞋们。若是有什么错误还请指出,有什么更好的方法也但愿能分享给我。感谢。

做者:一只小哈连接:https://www.jianshu.com/p/c35344d15278來源:简书著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
相关文章
相关标签/搜索