文档章节

SSO 单点登录会话管理

世界和平维护者
 世界和平维护者
发布于 2017/07/22 18:51
字数 2477
阅读 178
收藏 2

最近在公司的技术分享会中谈到了SSO相关的知识点,在此再做整理记录。本次分享来自Tate先生,在下只是一个大自然搬运工。其中涉及一些关于单系统登录,多系统分布式登录,微服务系统登录,没有代码,只讨论一些理论基础。

一、背景

单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

当今,各互联网公司言必称“生态”,行必是“跨界”,一个公司上的系统平台通常跑着多类业务,就算是单个产品,为了支撑海量用户,产品下的多个业务模块也会按分布式架构去拆分成多个子服务系统来实现,这样一来,各个系统或子服务系统之间的登录验证即有必要做统一的登录和退出处理。比如登录淘宝网之后 ,即可访问淘宝系的各类服务,包括淘宝网、天猫、阿里旅行、聚划算等,同样如果未登录时,在淘宝的各个服务里边点击登录按钮都是跳到同个登录页面。

所以,单点登录的几乎是当下互联网公司信息系统架构的标配,而授权第三方系统访问的开放平台架构是高配。本期以下内容主要讲单点登录的原理和实现思路,后续如有机会再说开发平台架构。

二、单系统登录机制

1、HTTP 无状态协议

HTTP是Hyper Text Transfer Protocol的缩写,顾名思义,这个协议支持着超文本的传输。

对于BS系统,通信机制都是基于http协议,而http是无状态的,即是说每个请求都是独立处理,服务端处理任何一个http请求时,如果只是基于http协议不做其他处理,服务端对于该请求是无知的,它并不知道究竟是A用户A发起的请求,还是用户B发起的请求,自然也就不知道A或者B是否发起了其他请求。任何一个请求都被当成独立的任务,处理完之后就释放了资源,无从追踪。如下图所示:

2、登录会话机制

随着时间的推移,人们发现静态的HTML着实无聊而乏味,增加动态生成的内容才会令Web应用程序变得更加有用。于是乎,HTML的语法在不断膨胀,其中最重要的是增加了表单(Form);客户端也增加了诸如脚本处理、DOM处理等功能;对于服务器,则相应的出现了CGI(Common Gateway Interface)以处理包含表单提交在内的动态请求。在这种客户端与服务器进行动态交互的Web应用程序出现之后,HTTP无状态的特性严重阻碍了这些应用程序的实现,毕竟交互是需要承前启后的,简单的购物车程序也要知道用户到底在之前选择了什么商品。于是,两种用于保持HTTP连接状态的技术就应运而生了,一个是Cookie,而另一个则是Session。

而想要做到基于HTTP这种轻量级无状态的协议,同时又要让服务器记住发起请求的客户端,就需要双方配合:

1、找个信物让服务端识别这个客户端,一般我们说是会话ID;

2、客户端和服务端各自珍藏这个信物;

3、每次客户端请求服务端时都要带上这个信物;

对于第1点,会话ID一般由服务端产生,只要唯一标识(令牌)这个客户端即可,在JAVA服务端一般用UUID生产一个即可。第2点,双方存储这个会话ID就可以根据自己方便选择存储方式,一般browser客户端可以存在cookie、localstorage等,服务端可以存在内存、数据库(redis、memcache)等。第3点,因为每次http请求都要带上,按照http结构,可以存放的地方可能有url参数、header、cookie,session。

三、登录状态

有了会话机制,那么服务端就能识别每个发过来的请求的是由哪个客户端发起的,而每个客户端之前是否有过请求,请求做了什么处理都可以记住。此时,而登录状态实际上是相当于服务端在存储会话ID的地方同时标明这个会话ID已经登录过了,再对这些已经登录的客户端会话允许他做更多的事情。

1、单系统登录

单系统的登录大致如下图:

客户发起的请求之后,客户端的令牌被记录在当前的ECS机器上的缓存/数据库中,每次请求到达服务端之后,服务端会校验当前的令牌是否允许通过,单系统登录机制相对来说比较简单。因为登录机制的技术点在于令牌配对,服务端如何维护令牌的问题(客户端维护令牌交给终端去处理即可),当涉及到单系统多实例的问题,如下图,单点登录将如何处理?

2、多系统登录

随着用户的激增,单系统的架构根本无法满足业务的需求,业界提供的一套较为普遍的解决方案是水平扩展:ECS机器+nginx反向代理来解决请求数激增的问题(成本较低,维护不难)。将这些请求分发到不同的机器去做处理。这样的架构比起单系统的应用架构来说,有了很好的扩展,来解决并发问题。但是这里就存在一个问题:登录信息要存储在哪个机器上?

如果单纯将令牌保存在某一台机器上,服务端处理请求之后,记录这个令牌,同时还要通知其他所有的机器,说:“Hello,XXX用户已经登录了,它的令牌是YYY,你们都记下了,以后XXX用户的请求都不能再拦截了。”

除了这种方式之外,也可以利用nginx的特性,将同样的IP转发到同样的机器上(IP哈希),除此之外,还有更好的解决方案吗?很明显,通知各个服务器去更新令牌,将登录信息保存在本地的数据库中,既浪费资源,同时也存在一定的时延,机器之间数据同步往往需要一定的时间(即便利用数据库的同步机制)。IP哈希更不是良策,如今海量用户上网,IP哈希非常容易出现某台机器过载而部分机器又闲适的问题。

我们系统前期采用的高速缓存redis来解决登录问题:

将所有的登录信息记录在一个缓存服务器中,客户端发起请求登录之后,令牌保存在缓存服务器的redis上,其他的请求在转发到不同机器的时候,需要去同一个缓存服务器上取令牌信息来判断。客户端退出之后,直接在缓存服务器上清除登录信息,并不需要再去通知其他服务器。其他服务器收到请求查不到令牌之后,再拦截请求,提示登录即可。这种情况基本上不会出现大的时延,没有数据同步的问题,但是弊端则是每次请求要到去另外的服务器去取令牌信息,相当耗,不过相较与其他方案来说,这个方案是较优的,毕竟现在的网速已经越来越快。

除了多系统之外,另外一种多系统则是目前较为流行的“微服务”架构了。核心思想就是:将一个大的应用进行合理拆分成各个微应用,各种好处~不过入坑慎重。

在微服务架构中,网关中心会拦截所有的请求,然后再由网关中心做转发到各个应用上去做业务处理,子应用之间也可以相互通信来解决业务问题。并且,子应用是不校验登录信息的,也就是说微服务是信任请求的,它会认为这个请求要么是开放的,要么已经经过网管中心的令牌校验了。所以网关中心上做登录信息的校验,所有请求都必须经过网关中心。

网关心本身就是一个微服务。从上图可以简单的get到一些信息,网关中心有点类似nginx,也在做转发处理,但是因为它也是一个Java应用,我们可以对它做更多事(基于业务的考虑),而nginx更多的可能是作为一个插件来解决一些诸如转发,负载均衡上的问题。当然,nginx 也有自己的优点,两者不能一概而论,因为所做的事也不尽相同,两个也可以相结合使用,不存在谁优谁差的问题。

单点登录大概就是这样的一套解决方案,我们目前也一直在使用后边两种解决方案,后边可能全部拆分成微服务架构也说不定。

 

 

 

© 著作权归作者所有

共有 人打赏支持
世界和平维护者
粉丝 7
博文 51
码字总数 76601
作品 0
深圳
程序员
私信 提问
统一用户权限管理系统 TDog7

(该系统已停止更新,已发布另外一个平台,演示地址:http://itgap.net) 系统名称:统一用户权限管理系统 简介:本系统为统一的细粒度授权管理和用户统一身份管理及单点认证支撑平台。每个接入...

蔡蜘蛛侠
2015/01/07
0
5
单点登录原理与简单实现

一、单系统登录机制 1、http无状态协议 web应用采用browser/server架构,http作为通信协议。http是无状态协议,浏览器的每一次请求,服务器会独立处理,不与之前或之后的请求产生关联,这个过...

余平的余_余平的平
2017/11/03
0
0
单点登录原理与简单实现

一、单系统登录机制 1、http无状态协议 web应用采用browser/server架构,http作为通信协议。http是无状态协议,浏览器的每一次请求,服务器会独立处理,不与之前或之后的请求产生关联,这个过...

skymyyang
2016/12/19
23
0
cookie+memcached实现单点登陆

10年的时候在iteye的第一篇文章记录了一下当时怎么实现我们系统的单点登陆。不过那个时候文章写的不好,思路也很浮躁,很难看懂,在csdn的第一篇技术博客打算重新温顾一下当时实现单点登陆的...

吞吞吐吐的
2017/10/18
0
0
bboss 会话共享框架 4.0.8 发布

bboss 会话共享4.0.8发布 bboss 会话共享功能特点: 作 用:为应用提供统一会话管理功能,避免集群部署场景下负载切换session丢失问题; 跨域跨应用共享会话并实现SSO功能;解决了会话共享五...

bboss
2015/08/02
3.2K
16

没有更多内容

加载失败,请刷新页面

加载更多

Jrebel 激活服务,在springboot上面的进行热部署

1.安装JRebel 下载Jrebel插件,官网需要翻墙下载,需要的可以在csdn的下载区去进行下载 打开idea,File->settings 然后重启idea 2.破解JRebel 首先HELP -> JRebel -> Activation 在jrebel se...

glen_xu
50分钟前
1
0
设置版头的图片+网页布局

1.div的background-image(推荐) 2.div+image 1.是只有部分图,2是压图 1.frame 2.js(推荐) 因为frame不好设置大小

木之下
54分钟前
0
0
MyBatis组件之缓存实现及使用

一 .概述 先讲缓存实现,主要是mybatis一级缓存,二级缓存及缓存使用后续补充 Mybatis缓存的实现是基于Map的,从缓存里面读写数据是缓存模块的核心基础功能; 除核心功能之外,有很多额外的附...

Ala6
今天
1
0
SpringBoot中使用@RequestBody时如何自定义需要转换的日期格式

SpringBoot序列化和反序列化Json时默认使用的是Jackson(例如使用@RequestBody反序列化前端传递过来的Json字符串时), 当我们前端使用Json字符串传递到后台时日期格式可能是时间戳(即long类...

帅得拖网速
今天
1
0
可自定义扩展底部列表对话框ListBottomSheetDialogFragment

因为需要,为了方便,构建了一个可以自定义扩展的底部列表对话框,可以应付大部分场景。 效果图如下: 1.默认实现: 2.自定义列表实现 3.自定义头部和列表实现 一.可实现功能 1.默认可实现通...

明月春秋
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部