JWT可以用于单点登录
单点登录是我比较喜欢的一个技术解决方案,一方面他能够提高产品使用的便利性,另一方面他分离了各个应用都需要的登录服务,对性能以及工作量都有好处。
自从上次研究过JWT如何应用于会话管理,加之以前的项目中也一直在使用CAS这个比较流行的单点登录框架,所以就一直在琢磨如何能够把JWT跟单点登录结合起来一起使用,尽量能把两种技术的优势都集成到项目中来。本文介绍我从CAS思考得出的SSO的实现方案。
其实CAS这个方案很好,非常强大,它最新的版本已经集成JWT了,所以要是不想自己开发单点登录的服务的话,完全可以考虑使用CAS。但是我认为,我们在做项目的时候,也许一开始并不需要这么强大的产品,CAS提供的登录形式有很多,而我们只需要应用其中的一种;
而且它这个框架正是因为强大,所以也会比较复杂,简单上手容易,但是遇到一些特殊的需求,比如我们想在CAS里面加入微信登录,那就需要对它的原理以及API有比较深入的了解才行。综合考虑,还是弄清楚CAS的原理,自己来实现一个基本的SSO服务比较放心。
本文的内容需要对JWT和SSO有一个基本的了解,你可以从这两篇文章来了解JWT的用途:
http://www.cnblogs.com/lyzg/p/6067766.html
http://www.cnblogs.com/lyzg/p/6028341.html
还可以从下面的资料来了解SSO的内容:
https://baike.baidu.com/item/SSO/3451380?fr=aladdin
本文主要是通过时序图的方式来介绍JWT SSO的实现原理,具体的技术实现暂时还没有,不过当你理解了这个方案的原理后,你会觉得最终的实现并不会特别复杂,你可以用任意的平台语言来实现它。
下面的时序图,模拟了三个服务,分别是CAS、系统A、系统B,它们分别部署在http://cas.com,http://systemA.com和http://systemB.com;CAS这个服务用来管理SSO的会话;系统A和系统B代表着实际的业务系统。我从五个场景分别来说明这个SSO方案的实现细节。下面先来看第一个。
场景一:用户发起对业务系统的第一次访问,假设他第一次访问的是系统A的some/page这个页面,它最终成功访问到这个页面的过程是:
_

_
图片点击放大看,下同
在这个过程里面,我认为理解的关键点在于:
还要注意的是:CAS服务里面的session属于服务端创建的对象,所以要考虑session id唯一性以及session共享(假如CAS采用集群部署的话)的问题。session id的唯一性可以通过用户名密码加随机数然后用hash算法如md5简单处理;session共享,可以用memcached或者redis这种专门的支持集群部署的缓存服务器管理session来处理。
由于服务端session具有生命周期的特点,到期需自动销毁,所以不要自己去写session的管理,免得引发其它问题,到github里找开源的缓存管理中间件来处理即可。存储session对象的时候,只要用session id作为key,session对象本身作为value,存入缓存即可。session对象里面除了session id,还可以存放登录之后获取的用户信息等业务数据,方便业务系统调用的时候,从session里面返回会话数据。
场景二:用户登录之后,继续访问系统A的其它页面,如some/page2,它的处理过程是:
**_

_**
从这一步可以看出,即使登录之后,也要每次跟CAS校验jwt的有效性以及会话的有效性,其实jwt的有效性也可以放在业务系统里面处理的,但是会话的有效性就必须到CAS那边才能完成了。当CAS拿到jwt里面的session id之后,就能到session 缓存服务器里面去验证该session id对应的session对象是否存在,不存在,就说明会话已经销毁了(退出)。
场景三:用户登录了系统A之后,再去访问其他系统如系统B的资源,比如系统B的some/page,它最终能访问到系统B的some/page的流程是:
**_

_**
这个过程的关键在于第一次重定向的时候,它会把sid这个cookie带回给CAS服务器,所以CAS服务器能够判断出会话是否已经建立,如果已经建立就跳过登录页的逻辑。
场景四:用户继续访问系统B的其它资源,如系统B的some/page2:
**_

_**
这个场景的逻辑跟场景二完全一致。
场景五:退出登录,假如它从系统B发起退出,最终的流程是:
**_

_**
最重要的是要清除sid的cookie,jwt的cookie可能业务系统都有创建,所以不可能在退出的时候还挨个去清除那些系统的cookie,只要sid一清除,那么即使那些jwt的cookie在下次访问的时候还会被传递到业务系统的服务端,由于jwt里面的sid已经无效,所以最后还是会被重定向到CAS登录页进行处理。
以上方案两个关键的前提:
jwt本身是不可伪造,不可篡改的,但是不代表非法用户冒充正常用法发起请求,所以常规的几个安全策略在实际项目中都应该使用:
尤其是CSRF攻击形式,很多都是钻代码的漏洞发生的,所以一旦出现CSRF漏洞,并且被人利用,那么别人就能用获得的jwt,冒充正常用户访问所有业务系统,这个安全问题的后果还是很严重的。考虑到这一点,为了在即使有漏洞的情况将损害减至最小,可以在jwt里面加入一个系统标识,添加一个验证,只有传过来的jwt内的系统标识与发起jwt验证请求的服务一致的情况下,才允许验证通过。这样的话,一个非法用户拿到某个系统的jwt,就不能用来访问其它业务系统了。
在业务系统跟CAS发起attach/validate请求的时候,也可以在CAS端做些处理,因为这个请求,在一次SSO过程中,一个系统只应该发一次,所以只要之前已经给这个系统签发过jwt了,那么后续 同一系统的attach/validate请求都可以忽略掉。
总的来说,这个方案的好处有:
它的缺陷是:
本文从理论层面介绍了结合jwt来实现SSO的方案原理,希望它能帮助一些朋友更好的理解SSO以及它的实现方法。本文方案参考自CAS的实现流程,你可以从下面这个资料了解CAS的单点登录实现过程:
https://apereo.github.io/cas/4.1.x/protocol/CAS-Protocol.html
它的流程跟我这个差别不是特别大,但是从清晰层面来说,我写的还是要更明了一些,所以对比起来阅读,可能理解会更透彻些。
另外,这个方案考虑地不一定很全面,所以要是您发现了其中的问题,还请您帮忙指正,非常感谢。
作者:流云诸葛
链接:https://www.cnblogs.com/lyzg/p/6132801.html
Original url: Access
Created at: 2019-09-04 16:11:38
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论