分布式单点登录系统的实现系列分享之:底层逻辑篇

开篇序

这篇文章是公众号 “ 数据技术部落 ”的第一篇文章。“数据技术部落”是我个人的第二个自媒体。在2016年,我发起了数据分析部落,同步了公众号、知乎、微博、CSDN、阿里云栖等等专栏,通过这些渠道也认识了很多志同道合的朋友。数据分析部落分为了若干个交流小组:有 Python数据挖掘小组、R语言小组、数据科技竞赛小组等等。所以,关于数据挖掘、机器学习、Python、R、数据平台等等专题的分享,我还会放到数据分析部落中,保持更新不变。

在近些年的工作中,大数据,云计算、架构、算法、大前端、后端、运维等等也是我主要的工作内容,可能更偏向技术一点,对于编程语言而言,多与 Java 、GO、和 C# 相关,为了更垂直的分享我的技术经验,这些内容我都会放在“数据技术部落”这个公众号中。

从 2016年起,我可以算是国内最早一批做数据分析和数据挖掘自媒体的,我知道怎样才能“吸引”大家关注,但近些年,我觉得粉丝的多少是没有意义的事情,偶尔看到我早些年一些哗众取宠的文章,我也很惭愧。

毕竟,现在,我只想把有价值的技术经验分享给大家,仅此而已。

有一段时间,我都不打算分享什么文章了,一是我不想因为疫情来占用公众流量,二是我觉得我自己只想把我的职业道路走好,其他的杂事,我也懒得做了。可以,我有时想想,技术是可以让这个世界变得更好的,或者说有机会让这个世界变得更好。我的文章,我的分享,也许可以帮助大家,也许也可以帮助这个世界。

01 SSO 概述

单点登录就是从一个位置登录就可以直接访问其他互信的系统。当我从系统一执行的登录操作,当我们在执行系统二和系统三的时候,我们就不用再次执行登录操作,也就是避免了用户重复登录的过程。所以单点登录系统是核心业务系统起到辅助的作用。它是在整个系统群中,起到集成的辅助的作用。

1.SSO 整体结构

单点登录系统都包含哪些组成部分,每一部分都起到什么样的作用?

在这里插入图片描述

当用户对业务系统发起请求的时候,我们会把用户请求拦截下来,要进行授权验证,我们要检查当前用户是否有访问业务系统的权限,如果有权限我们就放行,让用户去访问业务系统,如果用户没有访问业务系统的权限,我们就要提供一个接口(或者是界面),让用户实现一个登录和授权的过程。

所以,我们单点登录系统第一核心部分就是认证中心

1)认证中心(SSO服务端核心)
  • 认证中心的作用:
    • i) 对用户发起的请求进行验证,验证它是否具有权限;
    • ii) 如果用户没有权限,我们要提供一个界面或者接口,让用户进行授权登录
2) 用户与账号系统、用户数据获取接口

用户要进行授权,就得有用户和密码这些信息,用户登录之后,我们还要知道用户的姓名、单位等等这些信息,在一个集成了单点登录的业务系统群中,通常我们会将用户和账号这个管理系统,统一的集中在单点登录系统中进行管理和设置。

  • 当业务系统要获取用户的账号和基本信息会怎么办呢?
    • 我们在用户于账号系统里还要提供一个用户数据的获取接口,让业务系统在需要用户数据的时候,通过访问接口来获得。
3) 客户端模块

当用户对业务系统进行访问的时候,首先我们要对它的访问进行拦截来判断它是否有权限,那我们图中红字部分,对用户进行访问拦截和验证是如何实现的呢?这就是我们单点登录系统的第3个重要组成部分,客户端模块;

2.一个核心的概念:令牌

我们要拦截用户的请求,我们反复提到授权和验证来判断当前用户是否有权限?那它是否有权限是如何验证的呢?在我们单点登录的系统中,有一个非常重要的概念叫 令牌(token)

打一个比喻,我们要进入业务系统有一道 “ 门 ” 。这道门就是我们的拦截系统,我们要进入这道门,每个用户的验证请求,它都有一把钥匙,我们要检查这个钥匙是否有效,如果钥匙有效我们就放行,让它访问业务系统,这把钥匙就是令牌,token。

3.SSO 认证流程(工作原理/工作过程)

在这里插入图片描述
当用户向一个业务系统发起请求的时候,我们客户端模块会将用户的请求拦截下来,然后从用户请求里面查找它是否存在令牌,如果 token 存在我们就要进一步验证 token 是否有效。如果 token 有效,那实际上就是有效的钥匙要开启有效的门,那我们就可以成功的访问资源。也就是通过两步验证:token 是否存在和 token 是否有效。如果令牌不存在我们就要实现一个跳转的过程,也就是我们在浏览器里执行一个 Redirect 操作,把用户重定向到单点登录系统的认证界面。

那 token 为什么有时候会无效,在后面分享的单点登录系统核心技术的时候,我们会说,token 这个钥匙是有有效期的,如果过期,我们也把它重定向到单点登录系统的认证界面。

实际是这个流程最重要的就是对权限验证的过程即:token 是否存在和 token 是否有效。

02 SSO 单点登录系统的核心技术

在我们SSO的认证流程中,始终有一个很关键的概念就是令牌。当用户发起一个业务请求的时候,我们要从用户的请求中获取一个唯一的标识,通过这个标识我们就能判断当前用户是否具有这个权限。这个唯一的标识我们就称作令牌。

  • 考虑的问题:在我们具体技术实现的过程中,我们使用什么技术指标来充当这个令牌比较合适?
  • 我们本次搭建的系统是基于B/S架构的,即浏览器服务器模式。浏览器的工作是基于 HTTP 协议的,那我们就要回顾一下 HTTP 协议的一些基础知识。

1.HTTP 协议

HTTP 协议是一种无状态的协议。所谓无状态协议就是指两次请求之间是相互不理解的,每一次请求都是独立的,是一种没有事务记忆能力的协议。

jacky 自己也找了很多资料,对于 cookie 和 session 的表述,我个人认为都不算恰当,我借鉴了下面的内容,对于cookie 和 session 这两个基础概念的解析,我认为还是比较恰当的。
在这里插入图片描述

2.COOKIE 和 SESSION

MAP 结构中的 key 就相对于 cookie ,value 就相当于 session
在这里插入图片描述

03 非企业级举例:深入浅出

做技术,写代码,最重要的是什么?jacky 总结的一句话:就是你知道你该做什么,你所引用的技术处在一个什么样的层次。这之前,最重要的就是懂得逻辑!

在这里插入图片描述

1. 流程图概览

先概览一下我们的流程图,根据流程图,我们的颜色分成了三个部分:

  • 无颜色的这部分是我们客户端要实现的功能以及它实现的流程;
  • 蓝色的部分是我们的认证中心要实现的功能和流程;
  • 绿色的部分是我们业务系统的部分;

2. 流程图解析

1)单点登录

我们的流程从用户请求开始,用户向业务系统发起一个请求,我们首先要判断这个请求是否要拦截,并不是所有的请求都需要拦截,只有我们需要授权的请求才会被拦截。如果用户的请求是不需要被拦截的,那我们直接让用户去访问业务系统,一个请求就完成了。如果用户的请求需要被拦截,首先从用户的请求从提取令牌,如果令牌不存在,说明用户从来没有进行过授权登录,这个时候我们把页面跳转到认证授权中心的页面,进入蓝色的认证中心授权登录的流程,如果登录失败,授权失败,请求结束。如果,登录成功,下面是重要的部分:首先我们要生成令牌,并且我们要把这个令牌和用户的信息一起存入一个 MAP结构中,起到的作用就是,当下一次在持有这个令牌进行有效性验证的时候,我们可以在MAP结构中查找对应的令牌是否有对应的用户信息,如果有就说明令牌是有效的,如果令牌没有对应的用户信息,就说明这个令牌失效,我们把令牌作为 key ,用户信息作为 value 存储。令牌存储之后,我们还要把这个令牌发回给客户端(浏览器),所以我们会在 response 里面通过 addCookie 方法 生成一个新的 cookie, 这个 cookie 我们把它命名为 token,值为 token值。这样浏览器下次再发起访问的时候,就会把这个新的令牌记忆,用于我们令牌的有效性验证。这几个步骤做好之后,我们把浏览器重新定向到请求的这个页面。这个时候,刚才的请求就再一次被发起,这个时候token就是存在的,接下来,我们就要验证令牌的有效性,我们如果验证令牌的有效性呢?我们知道,令牌就是分配给我们的一个标识而已,这个标识具体的含义是由服务器持有的,所以为了验证令牌的有效性,我们需要把令牌发送给服务端,让服务端来验证,并把验证结果返回给我们。所以,令牌有效性的验证,需要我们客户端(浏览器)与服务器进行一次系统间的通信。首先,我们通过一定的系统间的通信方式,把令牌发给服务端,服务端接受了令牌之后,从我们刚才生成的这个 MAP 结构里,根据 token 来查找对应的 uid,如果这个token 对应的 uid 是存在的,就说明当前的令牌是有效的,这时,我们就找到了这个令牌对应的用户信息,服务端把这个uid 返回给客户端,客户端就成功的获取到了用户信息;如果我们从 MAP 结构里找不到对应的这个 uid,说明这个令牌是无效的,有可能是过期了,也有可能是伪造的,对我们来说,就是无意义的令牌,这个时候,我们的服务端向客户端返回 token 无效这样的错误代码,客户端也就无法的成功获取到 uid。当我们成功获取到 uid ,我们需要把获取到的用户信息附加到当前的请求之中,下边业务系统会提取我们的用户信息,会进行下一步的操作。

3) 单点退出

什么是单点退出,就是用户在任意位置执行了退出之后,对所有业务系统来说,我们的用户都是一种退出的状态,当用户让任意系统在发起用户授权请求的时候,我们都应该标注用户为未授权状态,这就是单点退出。

单点退出的实现:我们的用户请求直接把退出请求发送给我们的认证中心,我们的认证中心接受到我们的退出请求之后,从请求中提取出令牌,下面是关键操作,首先我们根据令牌,把 MAP 中对应的信息移除,这样即使用户在拿着这个令牌做有效性验证,因为 MAP 已经不存在令牌的对应信息,所以肯定会验证无效。但是,仅仅在MAP中移除了这个token,但是用户还是持有 token 的,每次都去执行无效的这样一个验证是比较浪费资源的,同时我们也应该把 token 这个 cookie 删除掉,最后在转到退出成功的页面。

原文地址:https://www.cnblogs.com/shujufenxi/p/14413645.html