看完这篇你不能再说不懂SSO原理了!

这一篇是原理篇,接下来还会有一篇实战篇,实战的相关代码是非常火的一个开源项目叫:xxl-sso
一、简介
单点登录(Single Sign On),简称为 SSO。
它的解释是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
所谓一次登录,处处登录。同样一处退出,处处退出。
二、背景
在我们企业发展初期的时候,企业内部使用的系统都会比较少,一般也就一个或者两个,每个系统有自己的登录功能。运营人员将自己的账号登录还是很方便。
但是随着公司的发展,公司的系统越来越多,比如有OA系统、CRM系统、财务管理系统、设备管理系统等,这个时候总不能每个系统都登录一遍吧,那真的会崩溃的。
合理做法是用户只需要登录一次就可以访问所有相互信任的应用系统。
三、回顾下单系统登录是怎么样的?
我们都知道,http是无状态的协议,这意味着当你登录成功后请求其它接口服务端也并不知道你之前登录过。那怎么办呢?
这个时候我们会想到Cookie+Session组合来解决http无状态问题。
如果说Cookie是检查用户身上的”通行证“来确认用户的身份,那么Session就是通过检查服务器上的”客户明细表“来确认用户的身份的。
那这里完整的登录流程应该是这样的:

1)、 首次登录验证成功之后,后端会将用户信息存在Session对象中。
2)、同时设置 Set-Cookie 字段,并把 SessionId 等信息写入进去,并设置过期时间,这些信息就是 Cookie。浏览器会保存这些 Cookie 信息
3)、之后在请求该系统其它接口的时候,因为是同域名,浏览器会自动在请求头上添加 Cookie 字段,并带上保存的 Cookie 信息。
4)、后端接受到请求后,会在请求头中取出 SessionId的值,然后再去服务器上的Session获取对于的用户信息,如果获取成功说明登录验证成功了,不需要再重复登录。
总结 根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。
所以,一般我们单系统实现登录会这样做:
- 登录:将用户信息保存在Session对象中 
- 如果在Session对象中能查到,说明已经登录
- 如果在Session对象中查不到,说明没登录(或者已经退出了登录)
 
- 注销(退出登录):从Session中删除用户的信息 
四、多系统登录会存在的一些问题?
我们说单系统中登录流程实现关键点在于  Cookie 和 Session的配合使用,但在多系统中就会存在很明显的两个问题
- 在多系统情况下服务端 Session不共享。
- 在多系统情况下客户端 Cookie不共享(跨域)。
如果能解决这两大难点,那实现多系统登录就简单多了
1.为什么会存在Session不共享?
我们说Session是存储在服务端的。
比如说现在有3台Tomcat服务器,当我们访问第1台Tomcat时,我们是可以将用户信息存在第1台Tomcat的Session中,但当我们访问第2台Tomcat的时候,这台服务器是
没有对应的Session数据,这就是所谓的Session不共享问题。
2、如何解决session共享问题呢?
说如何解决session共享问题呢,其实就是如何解决服务端数据共享问题
我们常见有3种解决方案:
第一种方案就是session拷贝。
当某一台Tomcat对session中的信息进行了修改都会同步给其他Tomcat,这样session就可以共享。
这种方案有三大缺陷
- 每一台服务器都会存储一份完整的session,增加服务器端压力也会浪费内存。
- 因为涉及到服务之间的同步,所以可能存在延迟。
第二种方案就是不通过session共享数据,而是采用redis。
redis纯天然解决了session不能共享的问题,而且redis除了存储查询效率高以外,还支持数据持久化功能,不用担心数据会丢失。
第二种方案也是现在现在企业级使用最多的一种方案。
第三种采用JWT。
我们在使用session或者使用redis,前端cookie其实只是存了个key,我们还需要拿着这个key到服务端的session,或者redis或者Mysql,总之都需要查一遍,但如果是JWT,
它最大的特点就是这个JWT本身就含有用户信息,服务端只要解析这个JWT成功,就可以获取用户信息。
3、为什么会Cookie跨域问题?
本质:由于浏览器安全策略,cookie只能在同一域名产生和使用
比方说,我们在请求www.a.com的时候,浏览器会自动把www.a.com的Cookie带去服务端。
但我们在请求www.b.com的时候,是不会把www.a.com下的Cookie带到b服务器的。
这就意味着由于域名不同,用户向系统A登录后,系统A返回给浏览器的Cookie,用户再请求系统B的时候不会将系统A的Cookie带过去。
至于如何解决Cookie跨域问题,不在这篇文章的讨论范畴内,下面实现单点登录的方式也不是通过解决Cookie跨域来实现的。
五、单点登录原理
相比于单系统登录,sso需要一个独立的认证中心,只有认证中心能接受用户的用户名密码等安全信息,其他系统不提供登录入口,只接受认证中心的间接授权。
1、SSO应用核心设计

应用系统:OA系统、CRM系统(需要登录的系统)
SSO客户端:登录、退出(独立jar包给应用系统引用)
SSO服务端:登录(登录服务)、登录状态(提供登录状态校验/登录信息查询的服务)、退出(用户注销服务)
数据库:存储用户账户信息(一般使用Mysql)
缓存:存储用户的登录信息(一般使用Redis)
2、SSO登录流程

对于这个流程图,我看网上问的最多的一个问题就是
根据同源策略:只要 协议+域名+端口号 一个不同,那么就不能进行跨域。www.oa.com 和 www.crm.com 域名都不相同了。也就是www.crm.com是
拿不到www.oa.com中cookie中的token的,那crm.com在请求的时候为什么不需要登录呢?
其实这个问题,上面的流程图已经很清楚了。它也并不是通过解决跨域问题来实现单点登录的。
它实现的核心原理在于:
个人用户请求www.oa.com时,因为oa.com的cookie下没有token信息,所以跳转到sso.com/login,因为是第一次登录,所以sso.com的cookie下也没有token信息,所以需要
用户输入账号密码登录,登录成功会在sso.com域名下保存token信息,同时会把token信息返回给oa.com。
这样oa.com和sso.com下的cookie都有token信息。
而第一次访问crm.com的时候,它下面是没有token信息,所以会跳转到sso.com/login进行登录,但因为sso.com域名下cookie已经有token信息,所以不用再输入账号密码信息
直接把token返回到crm.com就可以,这个过程用户是无感知的,所以也就实现了一次登录处处登录了。
3、sso注销流程

对于这个流程,问的比较多的是: oa.com退出登录了。如何做到让crm.com也需要重新登录的?
通过上面的流程图我们可以知道www.oa.com退出登录,只能去除oa.com和sso.com域名下cookie下的token,但是crm.com域名下的cookie还是可以获取token的,
那能获取就代表这可以正常访问www.crm.com的接口了吗?
其实不是的,因为我们还有校验token有效性这一步(令牌校验),我们拿着这个token去redis获取用户信息,其实已经获取不到了,因为上面退出登录的时候已经清除了,
所以令牌校验失败一样要重新登录。
声明: 公众号如需转载该篇文章,发表文章的头部一定要 告知是转至公众号: 后端元宇宙。同时也可以问本人要markdown原稿和原图片。其它情况一律禁止转载!
看完这篇你不能再说不懂SSO原理了!的更多相关文章
- 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?
		简介 Floyd-Warshall算法(Floyd-Warshall algorithm),是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以 ... 
- 看完这篇,还不懂JAVA内存模型(JMM)算我输
		欢迎关注专栏[JAVA并发] 更多技术干活尽在个人公众号--JAVA旭阳 前言 开篇一个例子,我看看都有谁会?如果不会的,或者不知道原理的,还是老老实实看完这篇文章吧. @Slf4j(topic = ... 
- [转帖]看完这篇文章,我奶奶都懂了https的原理
		看完这篇文章,我奶奶都懂了https的原理 http://www.17coding.info/article/22 非对称算法 以及 CA证书 公钥 核心是 大的质数不一分解 还有 就是 椭圆曲线算法 ... 
- 看完这篇Redis缓存三大问题,保你面试能造火箭,工作能拧螺丝。
		前言 日常的开发中,无不都是使用数据库来进行数据的存储,由于一般的系统任务中通常不会存在高并发的情况,所以这样看起来并没有什么问题. 一旦涉及大数据量的需求,如一些商品抢购的情景,或者主页访问量瞬间较 ... 
- APP的缓存文件到底应该存在哪?看完这篇文章你应该就自己清楚了
		APP的缓存文件到底应该存在哪?看完这篇文章你应该就自己清楚了 彻底理解android中的内部存储与外部存储 存储在内部还是外部 所有的Android设备均有两个文件存储区域:"intern ... 
- 关于 Docker 镜像的操作,看完这篇就够啦 !(下)
		紧接着上篇<关于 Docker 镜像的操作,看完这篇就够啦 !(上)>,奉上下篇 !!! 镜像作为 Docker 三大核心概念中最重要的一个关键词,它有很多操作,是您想学习容器技术不得不掌 ... 
- [转帖]看完这篇文章你还敢说你懂JVM吗?
		看完这篇文章你还敢说你懂JVM吗? 在一些物理内存为8g的服务器上,主要运行一个Java服务,系统内存分配如下:Java服务的JVM堆大小设置为6g,一个监控进程占用大约 600m,Linux自身使用 ... 
- 看完这篇还不会 GestureDetector 手势检测,我跪搓衣板!
		引言 在 android 开发过程中,我们经常需要对一些手势,如:单击.双击.长按.滑动.缩放等,进行监测.这时也就引出了手势监测的概念,所谓的手势监测,说白了就是对于 GestureDetector ... 
- Mysql快速入门(看完这篇能够满足80%的日常开发)
		这是一篇mysql的学习笔记,整理结合了网上搜索的教程以及自己看的视频教程,看完这篇能够满足80%的日常开发了. 菜鸟教程:https://www.runoob.com/mysql/mysql-tut ... 
- 看完这篇 Linux 权限后,通透了!
		我们在使用 Linux 的过程中,或多或少都会遇到一些关于使用者和群组的问题,比如最常见的你想要在某个路径下执行某个指令,会经常出现这个错误提示 . permission denied 反正我大概率见 ... 
随机推荐
- 【Spring系列】- Spring事务底层原理
			Spring事务底层原理 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目录 Sprin ... 
- 图扑 Web SCADA 零代码组态水泥生产工艺流程 HMI
			前言 水泥是建筑工业三大基本材料之一,素有"建筑工业的粮食"之称.2022 年 1-9 月水泥产量为 15.63 亿吨,生产方法包括新型干法.立窑.湿窑.干法中空窑和立波尔窑等. ... 
- 论文复现|Panoptic Deeplab(全景分割PyTorch)
			摘要:这是发表于CVPR 2020的一篇论文的复现模型. 本文分享自华为云社区<Panoptic Deeplab(全景分割PyTorch)>,作者:HWCloudAI . 这是发表于CVP ... 
- Linux面试题2:网络IO模型 & IO多路复用
			网络IO 先确定一下范围,我们讨论的都是网络IO,现阶段计算机早已经从CPU密集型转换成网络IO密集型,所以网络io的类型对于服务响应而言更重要. 五种IO模型 依据Unix的IO分类,网络IO分为五 ... 
- 树莓派编译opencv4
			前言 我用的是 树莓派3b 编译的 opencv4.1.0,如果不想编译可以直接下载我编译好的. 下载地址 直接 make install,或者按照我后续步骤复制动态链接库. 准备 需要调节虚拟内存大 ... 
- CheckBox 选中取值以及回填
			html: <td align="left" style="word-wrap:break-word;word-break:break-all;" col ... 
- 同一服务器部署多tomcat以及MyEclipse添加多tomcat
			tomcat有很多版本但他们的部署方式并不因为版本的不同而改变其的部署方式,操作者不必考虑此等原因.本人办公电脑使用的是tomcat7,家里自用的是6版本,这里就以6版本为例实现同一台机器上部署多to ... 
- 搭建漏洞环境及实战——在Linux系统中安装LANMP
			LANMP是Linux下Apache.Nginx.mysql和php的应用环境 演示的是WDLinux 命令:wget http://dl.wdlinux.cn/files/lamp_v3.tar.g ... 
- elementui中 分页在vue中的使用
			template中: <el-pagination background layout="prev, pager, next" :total="total&quo ... 
- 用友开发者中心全新升级,YonBuilder移动开发入门指南
			听说用友新上线了全新的开发者中心,有YonBuilder应用开发,集成开发.数据开发.智能与自动化.DevOps 等板块,本人作为用户老客户,对其中的移动开发比较感兴趣,本文重点讲解其中的移动开发平台 ... 
