看完这篇你不能再说不懂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 反正我大概率见 ...
随机推荐
- 重学c#系列——动态类型[二十二]
前言 该系列准备继续完善,一共108篇,持续更新. 正文 为什么有动态类型呢? 是因为很多东西天生就是动态类型的. 比如xml 和 json.cvs.数据库表,这些本来就是数据类型的. 在反射系列中提 ...
- 绵阳2020CCPC补题
绵阳2020CCPC D,K,J,L,G D. Defuse the Bombs 知识点:二分答案 复杂度:\(O(nlogn+log^2n)\) vp时我猜了一个结论,验了几个样例就写了,喜提WA3 ...
- WebApi如何启用Session并且使用
首先打开项目的Global.asax文件,重新方法init public override void Init() { //注册事件 this.AuthenticateRequest += WebAp ...
- 关于linux上steamplay无法启动windows游戏
前言 很多游戏,deepin-wine做的兼容性不如steamplay linux上steamplay加载windows游戏 点击添加游戏---------添加非steam游戏 点击浏览 改为all ...
- python-函数的参数与返回值
Python函数 4.1.函数初识 在编写程序的过程中,有某一功能代码块出现多次,但是为了提高编写的效率以及代码的重用,所以把具有独立功能的代码块组织为一个小模块,这就是函数 就是一系列Python语 ...
- 模拟Promise的功能
模拟Promise的功能, 按照下面的步骤,一步一步 1. 新建是个构造函数 2. 传入一个可执行函数 函数的入参第一个为 fullFill函数 第二个为 reject函数: 函数立即执行, 参数函 ...
- GKCTF2021 MISC
1.签到 当时没签上┭┮﹏┭┮: 追踪http流,发现依次执行[ls][ls/][whoami] 发现存在[fl4g],同时发现破解的规则为hex decode->base64 decode-& ...
- Flaks框架(Flask请求响应,session,闪现,请求扩展,中间件,蓝图)
目录 一:Flask请求响应 1.请求相关信息 2.flask新手四件套 3.响应相关信息(响应response增加数据返回) 二:session 1.session与cookie简介 2.在使用se ...
- 为什么NoSQL数据库这么受欢迎?
大数据时代,NoSQL数据库是企业构建数据能力的核心工具之一.近期,在2022腾讯全球数字生态大会NoSQL数据库专场上,腾讯云发布了多项NoSQL产品能力升级,并重点讲解了其背后的自研技术要点及实现 ...
- 沁恒微(WCH)CH395/392配置使用,代码指南 网路接口芯片 CH395 CH392
CH395/CH392相关资料可以从官网下载具体连接可以看博客:WCH以太网相关芯片资料总结 里面是WCH官网相关信息的链接. 也可以去Gitee上下载:Gitee链接. STM32控制CH395的例 ...