随着互联网的发展,web应用的复杂度也一直在提升,慢慢的单一的web应用已经不能满足复杂的业务需求。例如百度的搜索、新闻、百科、贴吧,其实本质上都是不同的网站。当用户使用这些平台的时候,我们当然不希望用户在每一个平台都有一个单独的账号,不然的话用户和开发者可能都会有想哭的冲动。所以我们就需要一种用户登录一次就可以访问所有相互信任的应用的系统,这种系统我们就管它叫单点登录(sso,Single Sign On)系统。
简单实现
在本系列的上一章的最后一节中我们介绍了基于cookie的认证模式,基于这种模式我们其实很容易实现一个单点登录系统。一般我们同一个系统的多个站点会在同一个顶级域名下(如,.baidu.com.cn),这样我们就可以让这些站点共享同一个顶级域名的cookie。这样只要一个站点登录了,所有的站点就都可以拿到登录认证信息。但是这种做法有两个缺点:
1、我们不一定能够保障我们所有的子系统都在同一个顶级域名下。
2、各个站点要分别实现一套登录认证功能。
鉴权与授权
在讨论如何解决仅仅基于cookie实现的单点登录系统的缺点之前,我们要先讨论另一个话题,就是鉴权与授权的分离。
我们一般说的登录系统指的是:识别用户身份,然后允许用户访问符合其身份权限的资源。这里边其实有两件事,识别用户身份这一步我们称之为鉴权,允许用户访问符合其身份权限的资源这一步我们称之为授权。在传统的单站点应用中,我们很少会将鉴权与授权分开来讨论,因为当时的登录功能简单。可是当代web站点的鉴权与授权都趋于多样化。比如在鉴权的时候我们可以使用账号密码、手机短信验证码、OAuth、人脸识别等等;同样不同站点对于授权的需求和权限的体系都是各不相同的。由于两者的多样化与不同,为了降低耦合,提高内聚,我们就有必要将鉴权与授权过程分开看待。
实现单点登录系统
当我们理解了鉴权与授权的概念之后,我们就很自然的会发现,一般来讲当各站点需要同一套认证体系的时候,其实他们的鉴权体系是统一的,而授权过程则可能各不相同。
我们来思考一下现实生活中我们是如何解决类似的问题的:当我们认定一个人是我们公司的员工的时候,我们就会有一个统一的部门制作和发放给我们员工一张工作证;然后员工更具这张工作证上的信息不同,决定了他在公司各个部门中能干什么不能干什么。
同样的我们可以制作一个统一认证站点来负责鉴权这步。当用户访问我们的一个站点的受保护资源的时候,我们先将用户重定向到统一认证站点;如果用户未登录,则跳到统一认证站点的登录界面进行登录,登录成功之后生成一个用户的身份票据(就像工作证一样),然后将票据信息返回给用户访问的站点;如果用户已登录,则跳过登录步骤,直接将用户的身份票据返回给用户访问的站点;然后不同的站点再根据自己的授权体系,决定用户是否能够访问响应的资源。
这样我们既解决了域名可能不统一的问题,又只需要实现统一分登录认证功能。