看完这篇你不能再说不懂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 反正我大概率见 ...
随机推荐
- Go实现常用软件设计模式二:工厂模式
目录: 举个栗子 概念介绍 使用场景 1.举个栗子 类图 ``` @startuml'https://plantuml.com/class-diagramclass Elephant { String ...
- php 高并发
1 swoole的博客 http://rango.swoole.com/archives/508 2 消息队列 3 接口并发请求
- zabbix6.0安装
一.简述 zabbix6.0 对相关软件版本要求较高,需要php7.25以上php8.0以下版本支持,若使用mysql数据库,其最低要求为mysql8.0,本此搭建采用的是使用较广的lnmp架构 za ...
- kubernetes_CoreDNS全解析
一.前言 kubernetes CoreDNS 是 kube-system 命令空间里面的一个Pod,用于域名解析. kubernetes自带三个命名空间(用kubeadm安装的Kubernetes集 ...
- Kubernetes_手把手打镜像并运行到k8s容器上(亲测可用)
一.前言 本文使用两个机器 192.168.100.150 是master节点,192.168.100.151 是node1 节点,如下: 演示三个示例,第一个示例wordpress博客系统是指将别人 ...
- Java 中你绝对没用过的一个关键字?
layout: post categories: Java title: Java 中你绝对没用过的一个关键字? tagline: by 子悠 tags: 子悠 前面的文章给大家介绍了如何自定义一个不 ...
- python之xlsx合并单元格
需求背景: 工作中将数据保存xlsx文件之后,里面每一列中有很多重复的看着很不美观,需要将每一列中的相同值合并起来,是表格看起来美观简洁 处理前 处理后 直接上代码(内涵注释讲解) "&qu ...
- 基于opencv实现简单人脸检测
作用:在视频中自动检测出人脸 使用内容:灰度转换,分类器,矩形框选,圆形框选,摄像头读取及释放 代码逻辑: 先读取摄像头后, 对摄像头拍摄到的图片进行逐帧分析, 并对图像进行灰度转换后使用类选择器识别 ...
- 为什么Git远程仓库中要配置公钥?
最近在使用阿里云效平台代码管理,首次使用新建仓库,使用SSH时需要配置公钥.之前也在GitHub.Gitee上配置过,每次都能正常使用,也没有思考过为什么要配置公钥.这次记录一下其中的原理. 本地和远 ...
- Chaos 测试下的若干 NebulaGraph Raft 问题分析
Raft 是一种广泛使用的分布式共识算法.NebulaGraph 底层采用 Raft 算法实现 metad 和 storaged 的分布式功能.Raft 算法使 NebulaGraph 中的 meta ...