SSO

410 阅读4分钟

SSO 单点登录
我理解这个是在企业的多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。说白了就是用户体验更好一点。
我们之前针对于单个系统的cookie和session那一套,就是用户第一次登录的时候,服务器会打开一个会话,比如tomcat会在会话中设置isLogin为true,这样用户的状态就是已登录,并且会生成sessionid,将这个sessionid放到一个cookie中带回浏览器,这样当浏览器下一次访问的时候,会携带这个域名下所有的cookie去访问,服务器找到cookie中的sessionid,根据sessionid寻找到服务器存储的session来获取用户是否登录的信息。
这用在一个系统上固然还好,那如果是一堆系统呢?每一个都登陆一下,先不说这样对于服务器存储的一个影响,用户不得烦死?所以针对于同一个派系的系统可以通过单点登录的方式来实现,一次登录全都欧克,一次注销全都完蛋。
那思路是什么呢?登录态本质上是在cookie上判断sessionid,那我们能不能搞一个服务器,登陆之后session在这个服务器上,然后返回cookie,登录一个系统的时候去判断是否登录都去这个地方验证一下?思路不错,就是所谓的共享cookie,但是cookie存在跨域的问题,你确实可以把cookie设置为一个顶级域名,然后所有的系统都设置为这个顶级域名下的地址,先不说这个的麻烦,除了这个以外还有用共享cookie的话,实现的技术(至少是服务器的技术)都要是一样的,不然返回的cookie的key不同,比如tomcat叫做JSESSIONID等等,最后cookie还是不安全的,那怎么办?
所以现在就可以说一下单点登陆了。
单点登录是在所有的系统之外有一个认证中心,只有认证中心能接受用户的用户名密码等安全信息,其他系统不提供登录入口,只接受认证中心的间接授权。间接授权也是通过令牌的方式并不是cookie。所以就是用户的用户名和密码发到了认证中心,认证中心通过后生成了授权令牌,随后的跳转中发给了子系统,子系统利用这个授权令牌生成了局部会话,局部会话的生成方式就是之前的方式。

image.png

这个图的过程就是:

  • 用户访问系统1的资源,系统1发现其未登录,带着自己的地址作为参数跳转到认证中心。
  • 验证中心发现用户未登录,将用户引导到登陆页面
  • 用户输入信息登录
  • 验证中心验证用户填写的信息通过后,建立与用户的全局会话,并生成授权令牌,并带着令牌跳转到系统1的地址
  • 系统1检测到令牌后,携带令牌和自己的系统地址作为参数前往验证中心验证令牌是否有效
  • 验证中心验证令牌有效,注册系统1的地址(这个一般会存储在redis中),返回有效
  • 系统1使用该令牌创建与用户的会话,称为局部会话,返回受保护资源
  • 用户访问系统2的受保护资源,系统2发现用户未登录,带着自己的地址作为参数跳转到认证中心。
  • 验证中心验证用户已登录,跳转回系统2的地址,并附上令牌
  • 系统2携带令牌和自己的地址作为参数前往验证中心验证令牌是否有效
  • 验证有效则注册系统2,返回有效
  • 系统2使用令牌创建与用户的局部会话,返回受保护资源 (生成的局部会话id会和令牌有绑定)

那注销的过程也是显而易见的,当用户在某个子系统中点击注销,系统会根据会话id得到相关的令牌,向验证中心发起注销请求,验证中心验证该令牌有效,销毁全局会话,并取出该令牌的所有注册系统地址,向所有的注册系统发起注销请求,各系统收到注销请求销毁局部会话,验证中心将用户引导到登陆页面。可以参考大佬画的如下的图。

image.png