1.SSO 解决什么问题
SSO 即单点登录技术。它解决的问题是:用户 u 需要访问系统 A,用户 u 由系统 B 掌控,u 访问 A 的行为由 B 掌控:B 授信 u 访问 A,但不想暴露 u 的信息给 A。有很多应用场景与此类似,如 QQ 授信用户登录人人网,但不想让人人网拿到用户的信息,如密码,好友,爱好等等。还有另外一个好处,处于一个容器内的所有系统只要有一个登录了,其它系统都可以使用这个登录信息被访问。
2.SSO 原理
SSO 的原理可以这样描述:用户 u 首次访问系统 B,B 将 u 定向到系统 A 的登录校验页面 v 并附加如果登录成功需要定向到 B 系统的页面 p。A 对 u验证,并记录登录状态。若 u登录成功,则 A 将 u 定向到B 的 p 页面。否则循环 v页面。
以上动作即可完成 A 对 u 完成授信并访问 B。流程如下:
图中的蓝色有向线条表示发送请求,线条上的数字表示是第几步;
绿色有向线条表示收到回应,线条上的数字表示 HTTP 状态码。302 表示重定向:对于终端发送的请求,服务器端给出一个状态为 302 的应答并附加一个地址 np 表示终端应该重新访问 np;
以上:
1.用户 u 请求 B 系统页面 v ,B 返回给 u 302 状态,欲将 u 重定向到 A 系统的登录页面 p;
2.u 向 A 的页面 p 发起请求,A 返回 p 页面给 u,等待输入;
3.u 在 p 页面输入正确的用户名及密码,发送请求给 A,通过校验后,A 返回 302 给 u,欲将 u 重定向到 B 系统的 v 页面;
4.u 向 B 的页面 v 发起请求,B 返回 v 页面给 u,完成请求流程。
这里面有一个细节没有谈到,在第四步里面,B 系统如何知道用户 u 的身份呢?CAS 协议于是规定了 ticket 来告之用户的信息。A 重定向的 v 页面其实还有一个请求参数:ticket。此时便有多种处理方案:
a).在 v 的后台去做一次解密 ticket (根据需要决定是否要从认证服务器使用 ticket 查询信息,有的设计直接将信息放于 ticket 中,有的则需要多一次查询),识别出当前用户
b).对于信息不存储于 ticket 中的设计,可以使用一个拦截器拦截第四步:在第四步前面拿到了 v 页面及 ticket ,对 ticket 解密,再使用 302 跳转到 v 页面,去掉 ticket 参数。这种设计一般是由认证服务器端提供一个库,此库对所有需要认证的系统在没有登录时发出的请求进行拦截,重定向到认证服务器,认证通过后再拦截请求对 ticket 解密,拿到了用户信息最终再跳转到真正的请求页面。
3.SSO 注销疑问
认证服务器提供的注销操作一般仅仅是一个链接,不带任何参数,如:http://192.169.10.1:443/cas/logout。乍一看觉得有些诡异,隐藏在任何应用后面的任何用户都可以打开这个链接执行注销,那么认证服务器是如何准确知道应该注销哪一个用户的呢?搞清楚了 SSO 的原理后这个问题很简单:每个用户其实都是直接与认证服务器交互的,虽然这种交互是被重定向的,但确实是用户直接在认证服务器上登录,而不是应用服务器在代理用户登录,搞清楚这点很重要!因此,认证服务器会建立与用户的连接,保存用户的 session,而用户终端会保存用户的 cookies,因此当用户打开上面的注销链接时,认证服务器就能知道是哪一个用户正在请求注销了!