夫天地者,万物之逆旅;光阴者,百代之过客。而浮生若梦,为欢几何?
架构师词条:单点登录(SSO)

SSO 标准定义

单点登录 Single Sign-On,简称 SSO,是一种控制多个相关但彼此独立的系统的访问权限, 拥有这一权限的用户可以使用单一的ID和密码访问某个或多个系统从而避免使用不同的用户名或密码,或者通过某种配置无缝地登录每个系统。

SSO 典型场景

上图有4个系统,分别是 A应用、B应用、C应用、和 SSO。A、B、C 均没有登录模块,而SSO只有登录模块,没有其他的业务模块,当A、B、C 需要登录时,将跳到SSO系统,在SSO系统完成登录后其他的应用系统也就随之登录了。这完全符合我们多系统单点登录的要求。

要实现单点登录(SSO),首先说说普通网站登录认证机制,即我们常说的 Cookie 和 Session。

当用户通过浏览器(Browser)首次访问并登陆一个网站的时候,Cookie的设置以及发送会经历以下4个步骤:  

客户端发送一个请求到服务器 --》 服务器发送一个HttpResponse响应到客户端,其中包含Set-Cookie的头部 --》 客户端浏览器保存cookie,之后向服务器发送请求时,HttpRequest请求中会包含一个Cookie的头部 --》服务器返回响应数据。

讲到这里相信大家已经明白了单点登录(SSO)需要做的事,就是如何做到 Cookie 或 Session 能在不同应用系统中共享,或是用户在 SSO 登录后 ,A应用、B应用、C应用 如何生成自己的 Cookie 或 Session 。

同域下SSO实现

只有一个域名,各业务系统部署在不同的二级域名下。比如域名 limitcode.com,同时有两个业务系统分别为:order.limitcode.com 和 car.limitcode.com。我们要做单点登录(SSO),需要一个登录系统,叫做:sso.limitcode.com。我们只要在 sso.limitcode.com登录,order.limitcode.com和car.limitcode.com就也登录了。

通过上面的登陆认证机制,我们可以知道,在sso.limitcode.com中登录了,其实是在sso.limitcode.com的服务端的Cookie 或 session中记录了登录状态,同时在浏览器端(Browser)的sso.limitcode.com下写入了Cookie。做过 Web 开发的都知道 Cookie 是不能跨域的,访问 order.limitcode.com 浏览器不能携带  sso.limitcode.com 保存的 cookie ,同理 sso.limitcode.com 生成的 session 也不能共享到 order.limitcode.com,因为 session 在自己应用的内存中。

针对 Cookie 不能跨域问题,我们可以在 sso.limitcode.com 应用中将 Cookie的域设置为顶域,即 .limitcode.com,这样所有子域的系统都可以访问到顶域的Cookie。

session 共享问题不同的web框架都提供了相应的方式解决,例如 Java 中有 Spring-Session 、.net 中可以基于数据库做session共享。

异域下SSO实现

同域下我们可以使用 Cookie 顶域的特性解决单点登录问题,异域的时候我们需要定义一套自己的单点登录方案,为了和其他系统能够有良好的对接,自己设计的单点登录方案应该遵循一些业界标准,此处我们以 CAS 这套单点登录标准流程说明如何实现异域的SSO。
CAS是Central Authentication Service的缩写,中央认证服务,一种独立开放指令协议,旨在为 Web 应用系统提供一种可靠的单点登录方法。其基本流程如下图所示:

1、用户首次访问app系统需要登录,跳转到CAS server,即SSO登录系统。  

2、SSO系统也没有登录,弹出用户登录页。 

3、用户填写用户名、密码,SSO系统进行认证后,将登录状态写入SSO的session,浏览器(Browser)中写入SSO域下的Cookie。 

4、SSO系统登录完成后会生成一个ST(Service Ticket),然后跳转到app系统,同时将ST作为参数传递给app系统。 

5、app系统拿到Ticket后,从后台向SSO发送请求,验证Ticket是否有效。  

6、Ticket验证通过后,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。


由此,实现了多系统下的单点登录。

登录成功后如何实现统一注销呢?即在app中注销,app2、sso 也会注销会话呢?  


用户向app发出注销请求,app 拿到与sso建立的 Ticket,向SSO认证中心发起注销请求,认证中心校验令牌有效,会销毁全局会话,同时取出此令牌注册的系统地址(app2),认证中心向所有注册系统发出注销请求,各系统收到注销请求后销毁局部会话,认证中心引导用户跳转至登录页面。

参考资料

单点登录(SSO)看这一篇就够了  

SSO  

Cookie和Session、SessionID的那些事儿  

深入理解Cookie  

Cookie/Session机制详解(非原创) 

单点登录原理与简单实现

单点登录实现原理(SSO)

漫谈单点登录(SSO)

CAS单点登录(一)——初识SSO

一篇文章彻底弄懂CAS实现SSO单点登录原理

作者:暗夜余晖

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

0

支持

0

反对

posted @2020-2-28  拜读(1895)

评论列表

评论内容:



喜欢请打赏

支付宝 微信

请放心支付