跳至主要內容

单点登录简介

wangdx大约 5 分钟

概述

  • 单点登录(Single-Sign-On),简称 SSO,它的解释为:在多个应用系统中,只要登陆一次,便可以访问其它相互信任的系统。早期系统由于只有一个服务,因此只需要登录一次,就可以访问系统的其它资源。伴随着业务的发展和用户数量的增加,单系统局限性越来越突出(无法支撑大规模用户、用户数量过多系统卡顿等)。为了增强系统的并发能力和解耦合,进行了系统业务的拆分,系统业务拆分后,为了保护系统之间数据安全性,用户需要登录认证才能进行资源访问。若资源分散在不同的服务上,每访问一次都需要重新登录,这会极大地降低用户体验感。解决上述问题的其中一种思路便是在一个系统登录,系统认证成功并返回一个令牌,用户访问其它系统时也携带该令牌,每个系统校验该令牌即可,若校验通过,便允许访问,反之拒绝访问请求,这便是早期单点登录的设计方案。
  • 如上图所示,当我们在浏览器(Browser)中访问一个应用时,用户需要完成登录认证(输入用户名和密码等),当认证成功后,在服务端(Server,这里 CloudApp 表示部署在云上的 Server)的 session 里会标记该用户的登陆状态为 yes(已登录),同时会往访问的浏览器(Browser)写入一个 cookie,这个 cookie 就是当前该用户登录的一个标识,用户每次访问服务时都会携带该 cookie,服务端会根据该 cookie 找到对应的 session,然后判断用户的状态。tomcat 部署的服务,默认登录后会返回一个名叫 jsessionid 的 cookie,jsessionid 对应的的 cookie 值就是改用户在服务器中的 sessionid,该值具有唯一性。

单点登录

单点登录分为:同根域单点登录、不同根域下单点登录。

  • 同根域下单点登录:一般一个企业只会有一个主域名,通过二级域名区分子系统。举个例子:一个企业中有三个子系统(app1.test.com、app2.test.com、sso.test.com),只要在 sso.test.com 系统中完成了登录验证,同时便在 app1.test.com、app2.test.com 中完成了登录。由 1.1 节可知,当用户在 sso.test.com 完成后,服务器会返回一个 cookie(携带 sessionid),用户下次访问时,会携带该 cookie 值服务器,服务器会根据 cookie 中的 sessionid 判断用户状态。由于浏览器是不能跨域的,因此 sso.test.com 中对应的 cookie 无法被携带至 app1.test.com、app2.test.com。

    • 解决该问题的方案:将 coockie 的域设置为顶域,即.test.com,这样所有子域的系统都可以访问到顶域的 cookie。我们在设置 cookie 时,只能设置顶域和自己的域,不能设置其他的域。解决了 cookie 共享问题,还有一个服务端 session 共享问题,由于是不同的服务,那么 session 如何共享呢?或许有一些常用的方法:

      • 1.Tomcat 集群 Session 全局复制(当数据量较大时,会影响 tomcat 性能,不建议);
      • 2.根据请求的 IP 进行 Hash 映射到对应的机器上(这就相当于请求的 IP 一直会访问同一个服务器)【如果服务器宕机了,会丢失了一大部分 Session 的数据,不建议】
      • 3.把 Session 数据放在 Redis 中(使用 Redis 模拟 Session)
  • 不同根域下单点登录:这里举个简单的例子,www.taobao.com和www.jd.com是两个不同的网站,浏览器不会把taobao.com的cookie带到jd.com下,因此无法实现cookie共享,这是因为不同的域名之间无法实现cookie共享(基于浏览器的安全机制)。针对这种情况要实现单点登录,需要借鉴CAS(Central Authentication Service)的设计思想。CAS 的设计思路主要如下图所示:

.

  • 1.用户访问某一个系统(假设该系统为 App1),App1 需要进行登录,用户现在处于未登录状态;
  • 2.此时 App1 会跳转到 CAS 服务端(即 SSO 登录系统),SSO 系统判断用户未登录,弹出登陆页面;
  • 3.用户输入用户名、密码等,SSO 系统认证成功后,将登录状态写入 session 中,同时将 sessionid 写入 SSO 域下的 Cookie 中,用户登录成功之后,SSO 会生成一个 ST(Service Ticket),然后重定向到 App1 系统(携带 ST),App1 系统拿到 ST 后,会从后台请求 SSO 服务,验证 ST 是否有效,验证成功后,App1 系统将登录状态写入 session 并设置 app 域下的 Cookie,并返回用户信息。

此时用户已完成登录,当再次访问 App1 时,会保持登录状态。当用户去访问系统 App2 时,由于 App2 未登录,App2 同样会去访问 SSO 系统,流程如下:

  • 1.App2 跳转到 SSO 系统;
  • 2.SSO 已经登录且生成了 ST,SSO 携带 ST 跳转到 App2 系统;
  • 3.app2 拿到 ST,后台访问 SSO,验证 ST 是否有效,验证成功后,App2 将登录状态写入 session,并在 App2 域下写入 Cookie。 用户访问 App2 系统,App2 系统没有登录,跳转到 SSO。

demo


上次编辑于: