关于sso:单点登录SSO看这一篇就够了

32次阅读

共计 2731 个字符,预计需要花费 7 分钟才能阅读完成。

背景

在企业倒退初期,企业应用的零碎很少,通常一个或者两个,每个零碎都有本人的登录模块,经营人员每天用本人的账号登录,很不便。
但随着企业的倒退,用到的零碎随之增多,经营人员在操作不同的零碎时,须要屡次登录,而且每个零碎的账号都不一样,这对于经营人员
来说,很不不便。于是,就想到是不是能够在一个零碎登录,其余零碎就不必登录了呢?这就是单点登录要解决的问题。

单点登录英文全称 Single Sign On,简称就是 SSO。它的解释是: 在多个利用零碎中,只须要登录一次,就能够拜访其余相互信任的利用零碎。

如图所示,图中有 4 个零碎,别离是 Application1、Application2、Application3、和 SSO。Application1、Application2、Application3 没有登录模块,而 SSO 只有登录模块,没有其余的业务模块,当 Application1、Application2、Application3 须要登录时,将跳到 SSO 零碎,SSO 零碎实现登录,其余的利用零碎也就随之登录了。这完全符合咱们对单点登录(SSO)的定义。

技术实现

在说单点登录(SSO)的技术实现之前,咱们先说一说一般的登录认证机制。

如上图所示,咱们在浏览器(Browser)中拜访一个利用,这个利用须要登录,咱们填写完用户名和明码后,实现登录认证。这时,咱们在这个用户的 session 中标记登录状态为 yes(已登录),同时在浏览器(Browser)中写入 Cookie,这个 Cookie 是这个用户的惟一标识。下次咱们再拜访这个利用的时候,申请中会带上这个 Cookie,服务端会依据这个 Cookie 找到对应的 session,通过 session 来判断这个用户是否登录。如果不做非凡配置,这个 Cookie 的名字叫做 jsessionid,值在服务端(server)是惟一的。

同域下的单点登录

一个企业个别状况下只有一个域名,通过二级域名辨别不同的零碎。比方咱们有个域名叫做:a.com,同时有两个业务零碎别离为:app1.a.com 和 app2.a.com。咱们要做单点登录(SSO),须要一个登录零碎,叫做:sso.a.com。

咱们只有在 sso.a.com 登录,app1.a.com 和 app2.a.com 就也登录了。通过下面的登陆认证机制,咱们能够晓得,在 sso.a.com 中登录了,其实是在 sso.a.com 的服务端的 session 中记录了登录状态,同时在浏览器端(Browser)的 sso.a.com 下写入了 Cookie。那么咱们怎么能力让 app1.a.com 和 app2.a.com 登录呢?这里有两个问题:

  • Cookie 是不能跨域的,咱们 Cookie 的 domain 属性是 sso.a.com,在给 app1.a.com 和 app2.a.com 发送申请是带不上的。
  • sso、app1 和 app2 是不同的利用,它们的 session 存在本人的利用内,是不共享的。

那么咱们如何解决这两个问题呢?针对第一个问题,sso 登录当前,能够将 Cookie 的域设置为顶域,即.a.com,这样所有子域的零碎都能够拜访到顶域的 Cookie。 咱们在设置 Cookie 时,只能设置顶域和本人的域,不能设置其余的域。比方:咱们不能在本人的零碎中给 baidu.com 的域设置 Cookie。

Cookie 的问题解决了,咱们再来看看 session 的问题。咱们在 sso 零碎登录了,这时再拜访 app1,Cookie 也带到了 app1 的服务端(Server),app1 的服务端怎么找到这个 Cookie 对应的 Session 呢?这里就要把 3 个零碎的 Session 共享,如图所示。共享 Session 的解决方案有很多,例如:Spring-Session。这样第 2 个问题也解决了。

同域下的单点登录就实现了, 但这还不是真正的单点登录。

不同域下的单点登录

同域下的单点登录是巧用了 Cookie 顶域的个性。如果是不同域呢?不同域之间 Cookie 是不共享的,怎么办?

这里咱们就要说一说 CAS 流程了,这个流程是单点登录的规范流程。

上图是 CAS 官网上的规范流程,具体流程如下:

  1. 用户拜访 app 零碎,app 零碎是须要登录的,但用户当初没有登录。
  2. 跳转到 CAS server,即 SSO 登录零碎, 当前图中的 CAS Server 咱们对立叫做 SSO 零碎。SSO 零碎也没有登录,弹出用户登录页。
  3. 用户填写用户名、明码,SSO 零碎进行认证后,将登录状态写入 SSO 的 session,浏览器(Browser)中写入 SSO 域下的 Cookie。
  4. SSO 零碎登录实现后会生成一个 ST(Service Ticket),而后跳转到 app 零碎,同时将 ST 作为参数传递给 app 零碎。
  5. app 零碎拿到 ST 后,从后盾向 SSO 发送申请,验证 ST 是否无效。
  6. 验证通过后,app 零碎将登录状态写入 session 并设置 app 域下的 Cookie。

至此,跨域单点登录就实现了。当前咱们再拜访 app 零碎时,app 就是登录的。接下来,咱们再看看拜访 app2 零碎时的流程。

  1. 用户拜访 app2 零碎,app2 零碎没有登录,跳转到 SSO。
  2. 因为 SSO 曾经登录了,不须要从新登录认证。
  3. SSO 生成 ST,浏览器跳转到 app2 零碎,并将 ST 作为参数传递给 app2。
  4. app2 拿到 ST,后盾拜访 SSO,验证 ST 是否无效。
  5. 验证胜利后,app2 将登录状态写入 session,并在 app2 域下写入 Cookie。

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

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

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

总结

单点登录(SSO)的所有流程都介绍完了,原理大家都分明了。总结一下单点登录要做的事件:

  • 单点登录(SSO 零碎)是保障各业务零碎的用户资源的平安。
  • 各个业务零碎取得的信息是,这个用户能不能拜访我的资源。
  • 单点登录,资源都在各个业务零碎这边,不在 SSO 那一方。用户在给 SSO 服务器提供了用户名明码后,作为业务零碎并不知道这件事。SSO 轻易给业务零碎一个 ST,那么业务零碎是不能确定这个 ST 是用户伪造的,还是真的无效,所以要拿着这个 ST 去 SSO 服务器再问一下,这个用户给我的 ST 是否无效,是无效的我能力让这个用户拜访。
正文完
 0