一文了解单点登录 SSO


概念

SSO 英文全称 Single Sign On,单点登录。

在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统。

优点

用户角度

用户能够做到一次登录多次使用,无需记录多套用户名和密码,省心。

系统管理员角度

管理员只需维护好一个统一的账号中心就可以了,方便。

开发角度

新系统开发时只需直接对接统一的账号中心即可,简化开发流程,省时。

技术实现

  • 登录流程图

登录流程图

系统A和系统B都是前后端分离的,比如前端框架用的 React/Vue/Angular,都是通过 NPM 编译后独立部署的,前后端完全通过HTTP接口的方式进行交互,也有可能前后端项目的域名都不一样。

SSO认证中心不是前后端分离的,就是前端代码和后端代码部署在一个项目中

  • 退出登录流程图

退出登录流程图

退出,还可以从SSO认证中心退出,然后调取各个系统的用户退出接口。

当用户再进行操作的时候,就会跳转到SSO的登录界面

CAS

什么是CAS

CAS 是 Central Authentication Service 的缩写,是由 Yale 大学发起的一个企业级的开源项目,旨在为 Web 应用系统提供一种可靠的 SSO 解决方案。

术语

  • Client: 用户
  • Server: 中心服务器,负责单点登录的服务器
  • Service: 需要使用单点登录的各个服务,各个系统。

核心票据

  • TGT(Ticket-Granting Ticket)

TGTCAS 为用户签发的登录票据,TGT 封装了 Cookie 值以及此 Cookie 值对应的用户信息。用户在 CAS 认证成功后, CAS 生成 cookie,写入浏览器,同时生成一个 TGT 对象,放入自己的缓存,TGT 对象的 ID 就是 cookie 的值。当 HTTP 再次请求时,如果有携带 CAS 生成的 cookie,则 CAS 以此 cookie 值为 key 查询缓存中有无 TGT,如果有,则判断用户之前登录过,如果没有,则判断没有登录。

  • ST(Service Ticket)

STCAS 为用户签发的访问某一 service 的票据。用户访问 service 时,service 发现没有 ST,则要求用户去 CAS 服务器获取 ST。用户向 CAS 发出获取 ST 的请求,
如果用户的请求包含 cookie,则 CAS 会以此 cookie 为 key 查询缓存中有无 TGT。如果存在 TGT,则此 TGT 签发一个 ST,返回给用户。用户凭借 ST 去访问 service, service 拿 STCAS 服务器验证,验证通过后,允许用户访问该资源。

  • TGTST 之间的关系

STTGT 签发的。用户在 CAS 上认证成功后,CAS 生成 TGT,用 TGT 签发一个 STST 的 ticketGrantingTicket 属性值就是 TGT 对象,然后把 ST 的值 redirect 到客户应用。

  • 结构体系

从结构体系看,CAS 包括两部分:CAS ServerCAS Client
CAS Server 负责完成对用户的认证工作,通过给用户签发两个重要的票据:登录票据(TGT)和服务票据(ST,Service Ticket)来实现认证过程,CAS Server 需要独立部署。
CAS Client 负责处理对客户端受保护资源的访问请求,对请求方进行身份认证时,重定向到 CAS Server 进行认证。准确来说,它以 Filter 方式保护受保护的资源。
对与访问受保护资源的每个 Web 请求,CAS Client 会分析该 HTTP 请求中是否包含 Service Ticket。CAS Client 与受保护的客户端应用部署在一起。

主要原理

基本过程:
CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护 Web 应用的受保护资源,过滤对客户端的每一个 Web 请求。

  • 第一步,Web 浏览器访问 CAS Client,无 session 并且无票据(ST),于是定向到 CAS Server
  • 第二步,CAS Server 检查到没有携带相关的 cookie,故服务端拿不到 TGC, 因此定向到登录页面,让用户登录。
  • 第三步,用户输入正确的用户名和密码,认证成功。 CAS 生成 cookie,写入浏览器,同时生成一个 TGT 对象,再根据 TGT 发放票据 ST,并且附带上 ST 重定向到 CAS Client。
  • 第四补,CAS Client 拿着 STCAS 发送请求确认 ST 的真实性,验证成功返回用户信息.

详细过程:

1、用户访问 CAS Client a, 域名是 www.a.cn
2、由于用户没有携带在 a 服务器上登录的 a cookie,所以 a 服务器返回 http 重定向,重定向的 url 是 CAS Service 的地址。同时 url 中的 query 参数中指明登录成功后,跳转回 www.a.cn。
3、由于该请求没有携带在 CAS Service 上登录的凭证 TGC,所以 CAS Service 判断用户未登录,给用户显示登录界面。
4、用户输入账号密码验证成功后,CAS Service 服务器生成一个该用户的 TGT,表明该用户已登录,同时返回一个 http 重定向到 a 页面,在重定向地址的 query 中包含 Service 根据 TGC 派发的 ST,重定向的 http response 中包含写 cookie 的 header。这个 cookie 的值是 TGC。
5、根据 ST,a 服务器向 CAS Service 发送请求验证票据的有效性。验证成功后,a 服务器确认用户已经在 CAS Service 登录了,于是 a 服务器构建用户登录的 session,记为 a session。并将 cookie 写入浏览器。此处的 cookie 和 session 保存的是用户在 a 服务器的登录状态,和 CAS 无关。
6、用户又访问 CAS Client b, 域名是 www.b.cn
7、由于用户没有携带在 b 服务器上登录的 b cookie,所以 b 服务器返回重定向到 CAS Service
8、重定向到 CAS Service,由于在第 4 步中,我们已经向浏览器写入了 TGC 的 cookie,所以此时 CAS Service 根据 cookie 去查找 TGT,可以找到就判断用户已经登录过,重定向到 www.b.cn
9、b 服务器根据票据向 SSO 服务器发送请求,票据验证通过后,b 服务器知道用户已经在 sso 登录了,于是生成 b session,向浏览器写入 b cookie。

流程图

`CAS`登录流程图

上图是CAS官网上的标准流程,具体流程如下:

  • 用户访问app系统,app系统是需要登录的,但用户现在没有登录。
  • 跳转到CAS server,即SSO登录系统,以后图中的CAS Server我们统一叫做SSO系统。 SSO系统也没有登录,弹出用户登录页。
  • 用户填写用户名、密码,SSO系统进行认证后,将登录状态写入SSO的session,浏览器(Browser)中写入SSO域下的Cookie。
  • SSO系统登录完成后会生成一个ST(Service Ticket),然后跳转到app系统,同时将ST作为参数传递给app系统。
  • app系统拿到ST后,从后台向SSO发送请求,验证ST是否有效。
  • 验证通过后,app系统将登录状态写入session并设置app域下的Cookie。

至此,跨域单点登录就完成了。以后我们再访问app系统时,app就是登录的。接下来,我们再看看访问app2系统时的流程。

  • 用户访问app2系统,app2系统没有登录,跳转到SSO。
  • 由于SSO已经登录了,不需要重新登录认证。
  • SSO生成ST,浏览器跳转到app2系统,并将ST作为参数传递给app2。
  • app2拿到ST,后台访问SSO,验证ST是否有效。
  • 验证成功后,app2将登录状态写入session,并在app2域下写入Cookie。

这样,app2系统不需要走登录流程,就已经是登录了。SSO,app和app2在不同的域,它们之间的session不共享也是没问题的。

有的同学问我,SSO系统登录后,跳回原业务系统时,带了个参数ST,业务系统还要拿ST再次访问SSO进行验证,觉得这个步骤有点多余。他想SSO登录认证通过后,通过回调地址将用户信息返回给原业务系统,原业务系统直接设置登录状态,这样流程简单,也完成了登录,不是很好吗?

其实这样问题时很严重的,如果我在SSO没有登录,而是直接在浏览器中敲入回调的地址,并带上伪造的用户信息,是不是业务系统也认为登录了呢?这是很可怕的。


文章作者: 江湖义气
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 江湖义气 !
  目录