SSO 单点登录

什么是JWT

        JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用间传输声明。它以一种紧凑且自包含的方式安全地在用户和服务之间传递信息,通常用于身份验证和信息交换

为什么要使用JWT

1.传统Session认证的弊端
        HTTP是一种无状态的协议,如果用户提供了用户名和密码来进行用户认证,认证通过后HTTP协议不会记录下认证后的状态,那么下一次请求时,用户还要再一次进行认证。

        解决:我们只能在用户首次登录成功后,在服务器存储一份用户登录的信息这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了。(基于cookie 和 session)

 这是传统的基于cookie 和 session认证的过程

然而,传统的session认证有如下的问题:

1. 随着用户的增多,服务器内存开销会明显增大(Session本质上是服务器中的一块内存区域)

2. 分布式场景下Session无法共享。 由于session是存在与服务器的物理内存中,所以在分布式系统中,这种方式将会失效。虽然可以将session统一保存到Redis中,但是这样做无疑增加了系统的复杂性。

3. 使用cookie的弊端,如果cookie被截获,用户很容易收到跨站请求伪造攻击(CSRF)。并且如果浏览器禁用了cookie,这种方式也会失效。

4. Cookie无法跨域,所以session的认证也无法跨域,对单点登录不适用

2. JWT认证的优势

1. 简洁,JWT Token数据量小,传输速度也很快

2. 跨语言,因为JWT Token是以JSON加密形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持

3. 不需要在服务端保存会话信息,也就是说不依赖于cookie和session,所以没有了传统session认证的弊端,特别适用于分布式微服务
4. 单点登录友好:使用Session进行身份认证的话,由于cookie无法跨域,难以实现单点登录。但是,使用token进行认证的话, token可以被保存在客户端的任意位置的内存中,不一定是cookie,所以不依赖cookie,不会存在这些问题
5. 适合移动端应用:使用Session进行身份认证的话,需要保存一份信息在服务器端,而且这种方式会依赖到Cookie(需要 Cookie 保存 SessionId),所以不适合移动端

JWT结构

JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终传输的字符串

        aaa.bbb.ccc 三部分的结构

JWTString=Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)

1.Header

JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存

{
  "alg": "HS256",
  "typ": "JWT"
}

2.Payload

有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 一般会把包含用户信息的数据放到payload中

{
  "sub": "1234567890",
  "name": "Helen",
  "admin": true
}

请注意,默认情况下JWT是未加密的,因为只是采用base64算法,拿到JWT字符串后可以转换回原本的JSON数据,任何人都可以解读其内容,因此不要构建隐私信息字段,比如用户的密码一定不能保存到JWT中,以防止信息泄露。JWT只是适合在网络中传输一些非敏感的信息

3.Signature

签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用header中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名

注意JWT每部分的作用,在服务端接收到客户端发送过来的JWT token之后:

        header和payload可以直接利用base64解码出原文,从header中获取哈希签名的算法,从payload中获取有效数据
        signature由于使用了不可逆的加密算法,无法解码出原文,它的作用是校验token有没有被篡改。服务端获取header中的加密算法之后,利用该算法加上secretKey对header、payload进行加密,比对加密后的数据和客户端发送过来的是否一致。注意secretKey只能保存在服务端,而且对于不同的加密算法其含义有所不同,一般对于MD5类型的摘要加密算法,secretKey实际上代表的是盐值

具体SpringBoot 的实现参考 JWT详解-CSDN博客文章浏览阅读10w+次,点赞921次,收藏4.5k次。本文从本人博客搬运,原文格式更加美观,可以移步原文阅读:JWT详解JWT简介1.什么是JWT在介绍JWT之前,我们先来回顾一下利用token进行用户身份验证的流程:客户端使用用户名和密码请求登录服务端收到请求,验证用户名和密码验证成功后,服务端会签发一个token,再把这个token返回给客户端客户端收到token后可以把它存储起来,比如放到cookie中客户端每次向服务端请求资源时需要携带服务端签发的token,可以在cookie或者header中携带服务端收到请求,然后去验证客户端请_jwt详解https://blog.csdn.net/weixin_45070175/article/details/118559272?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171057228216777224444421%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171057228216777224444421&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-118559272-null-null.142^v99^pc_search_result_base6&utm_term=JWT&spm=1018.2226.3001.4187

什么是SSO

        单点登录的英文名叫做:Single Sign On(简称SSO),指在同一帐号平台下的多个应用系统中,用户只需登录一次,即可访问所有相互信任的系统。简而言之,多个系统,统一登陆。

        类似之前实习的时候,平台只要登录一次就可以访问其他内部平台

        为什么需要做单点登录系统呢?在一些互联网公司中,公司旗下可能会有多个子系统,每个登陆实现统一管理,多个账户信息统一管理 SSO单点登陆认证授权系统。比如阿里系的淘宝和天猫,显而易见这是两个系统,但是在使用过程中,只要你登录了淘宝,同时也意味着登录了天猫。

总结:用户只需要登录一次就可以访问所有相互信任的应用系统。

什么是CAS 

        CAS(Central Authentication Service)是一种流行的SSO解决方案,它是一个开源的认证协议和实现。用于提供Web应用程序的SSO认证服务。

CAS是单点登录SSO的一种具体实现

        旨在为 Web 应用系统提供一种可靠的单点登录解决方法(SSO的一种框架)CAS 包括两部分:CAS Server 和 CAS Client

        有些又称CAS为跨域SSO。 设置专门SSO服务器,当两个产品不同域时,cookie无法共享,从而我们就需要搭建SSO服务器。

        CAS Server:负责完成对用户的认证工作 , 需要独立部署。

        CAS Client:负责处理对客户端受保护资源的访问请求,需要对请求方进行身份认证时,重定向到 CAS Server 进行认证。

CAS的几个重要知识点

接口

        /login:登录接口,用于登录到中心服务器。
        /logout:登出接口,用于从中心服务器登出

票据

1. TGT (Ticket Grangting Ticket) :TGT 是 CAS 为用户签发的登录票据,拥有了 TGT,用户就可以证明自己在 CAS 成功登录过。TGT 封装了 Cookie 值以及此 Cookie 值对应的用户信息。CAS 通过 Cookie 值(TGC)为 key 查询缓存中有无 TGT(TGC:TGT(key:value)),如果有的话就说明用户已经登录成。

2.TGC(Ticket Granting Cookie) :CAS Server 生成TGT放入自己的 Session 中,而 TGC 就是这个 Session 的唯一标识(SessionId),以 Cookie 形式放到浏览器端,每个请求都会尝试携带 TGC

3.ST(Service Ticket) :ST 是 CAS 为用户签发的访问某一 service 的票据。用户访问 service 时,service 发现用户没有 ST,则要求用户去 CAS 获取 ST。用户在访问其他服务时,发现没有 cookie 或 ST ,那么就会302到 CAS 服务器获取 ST。然后会携带着 ST 302 回来。

CAS的实现过程

跨域SSO(CAS)实现过程

1. 用户访问产品 a,域名是 http://www.a.cn

2. 由于用户没有携带在 a 服务器上登录的 a cookie,所以 a 服务器重定向到SSO 服务器的地址(重定向链接包含Service(当前请求CAS系统的应用系统的URL)参数)

3. 由于用户没有携带在 SSO 服务器上登录的 TGC,所以 SSO 服务器判断用户未登录,给用户显示统一登录界面。

4. 登录成功后,SSO 服务器构建用户在 SSO 登录的 TGT,同时返回一个 http 重定向到步骤1)中的Service(包含 sso 服务器派发的 ST )。  

这里注意:

  • 重定向地址为之前写在 query 里的 A 页面。
  • 重定向地址的 query 中包含 SSO 服务器派发的 ST。
  • 重定向的 http response 中包含写 cookie 的 header。这个 cookie 代表用户在 SSO 中的登录状态,它的值就是 TGC

5. 重定向的 http response 中包含写 cookie。这个 cookie 代表用户在 SSO 中的登录状态,它的值是 TGC

6. 浏览器重定向到产品 a。此时重定向的 url 中携带着 SSO 服务器生成的 ST。根据 ST,a 服务器向 SSO 服务器发送请求,SSO 服务器验证票据的有效性。验证成功后,a 服务器知道用户已经在 sso 登录了,于是 a 服务器构建用户登录 session。应用系统页实现了用户认证

7. 用户访问产品 b,域名是 http://www.b.cn。

8. 由于用户没有携带在 b 服务器上登录的 b cookie,所以 b 服务器重定向到SSO 服务器,去询问用户在 SSO 中的登录状态。(重定向链接包含Service(当前请求CAS系统的应用系统的URL)参数)

9. 浏览器重定向到 SSO服务器。由于已经向浏览器写入了携带 TGC 的cookie,所以此时 SSO 服务器可以拿到,根据 TGC 去查找 TGT,如果找到,就判断用户已经在 sso 登录过了。

10. SSO 服务器返回一个重定向,重定向携带 ST

11. 浏览器带 ST 重定向到 b 服务器。b 服务器根据票据向 SSO 服务器发送请求,票据验证通过后,b 服务器知道用户已经在 sso 登录了,于是生成 b session,向浏览器写入 b cookie。应用系统页实现了用户认证

基于JWT集成CAS的方法思路

1. 应用登录页面重定向到CAS系统的登录页面,URL包含Service参数标识当前需要登录的服务;

2. 用户在CAS登录页面输入认证信息登录成功后,CAS服务器端根据步骤A的Service参数自动重定向到单页Web应用,重定向链接包含CAS生成的ST参数。

3. 单页Web应用以TicketService为参数,请求SSO服务器API服务端鉴权接口;

4. API服务端接口收到请求后,以Ticket、Service为参数,调用CAS ProxyValidate校验接口;

5. 如果校验通过,CAS服务端返回用户信息,API服务端根据HS256算法、用户信息、过期时间生成JWT,返回给单页Web应用,单页Web应用在localStoage或Cookie保存JWT;校验不通过则返回Ticket无效;

6. 后续单页Web应用请求API服务端接口,请求头携带JWT,进行鉴权;如果鉴权失败或JWT已过期,则返回错误;否则返回单页Web应用请求的信息;

        用户登录单页Web应用时,只需要携带Service参数重定向到CAS服务器进行登录,用户的敏感信息(比如账号、密码)不经过API服务端;API服务端不需要保存用户的登录状态;API服务端采用RESTful的架构方式设计API,使用JWT认证方式,解决了跨域的问题;JWT自带有效期,超过有效期后,需要重新单页Web应用重新登录获取JWT,增强了系统的安全性。

        CAS工作方式是,用户在登录到一个CAS认证中心后(CAS Server),可以访问其他受同一认证中心保护的应用程序,而无需再次提供凭据。CAS通过使用票据(ticket)来管理用户会话,并通过票据验证来授权用户访问不同的应用程序。

 

跨域下的单点登录

如果是不同域呢?不同域之间Cookie是不共享的,怎么办?

这里我们就要说一说CAS流程了,这个流程是单点登录的标准流程。

具体流程如下:

1)用户访问app系统,app系统是需要登录的,但用户现在没有登录。
2)跳转到CAS server,即SSO登录系统,以后图中的CAS Server我们统一叫做SSO系统。 SSO系统也没有登录,弹出用户登录页。
3)用户填写用户名、密码,SSO系统进行认证后,将登录状态写入SSO的session,浏览器(Browser)中写入SSO域下的Cookie。
4)SSO系统登录完成后会生成一个ST(Service Ticket),然后跳转到app系统,同时将ST作为参数传递给app系统。
5)app系统拿到ST后,从后台向SSO发送请求,验证ST是否有效。
6)验证通过后,app系统将登录状态写入session并设置app域下的Cookie。

至此,跨域单点登录就完成了。以后我们再访问app系统时,app就是登录的。接下来,我们再看看访问app2系统时的流程。

1)用户访问app2系统,app2系统没有登录,跳转到SSO。
2)由于SSO已经登录了,不需要重新登录认证。
3)SSO生成ST,浏览器跳转到app2系统,并将ST作为参数传递给app2。
4)app2拿到ST,后台访问SSO,验证ST是否有效。
5)验证成功后,app2将登录状态写入session,并在app2域下写入Cookie。

        这样,app2系统不需要走登录流程,就已经是登录了。SSO,app和app2在不同的域,它们之间的session不共享也是没问题的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/461620.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解密学习机制:线性回归与梯度下降之旅

摘要 在理解机器学习机制的过程中,我们探讨了在合成数据集上训练简单线性回归模型的过程。整个过程要解决的问题是算法如何通过迭代优化来学习输入和输出变量之间的基本关系。 我们的方法包括生成一个合成线性数据集,实施梯度下降进行参数估计&#xf…

Sonarqube中Java规则与CWE与OWASP的映射关系

很多企业使用Sonarqube社区版作为静态分析工具,在开发阶段检测代码中的缺陷或安全漏洞。但是如果是作为SAST工具厂商,集成该引擎,则需要把Sonarqube中的检测规则与其它引擎的规则进行整合,例如下图,把Sonarqube中的一些…

Spring Cloud Alibaba微服务从入门到进阶(三)(Spring Cloud Alibaba)

Spring Cloud Alibaba是spring Cloud的子项目 Spring Cloud Alibaba的主要组件(红框内是开源的) Spring Cloud是快速构建分布式系统的工具集, Spring Cloud提供了很多分布式功能 Spring Cloud常用子项目 项目整合 Spring Cloud Alibaba …

Java项目:56 ssm681基于Java的超市管理系统+jsp

作者主页:舒克日记 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 功能包括:商品分类,供货商管理,库存管理,销售统计,用户及角色管理,等等功能。项目采用mave…

【考研数学】高等数学总结

文章目录 第一章 极限 函数 连续1.1 极限存在准则及两个重要极限1.1.1 夹逼定理1.1.1.1 数列夹逼定理1.1.1.2函数夹逼定理 1.1.2 两个重要极限1.1.2.1 极限公式11.1.2.1.1 证明1.1.2.1.2 数列的单调有界收敛准则1.1.2.1.2.1 二项式定理1.1.2.1.2.2 证明 1.1.2.2 极限公式21.1.2…

【Linux进程信号】信号的发送与保存

【Linux进程信号】信号的发送与保存 目录 【Linux进程信号】信号的发送与保存阻塞信号1. 信号其他相关常见概念2. 在内核中的表示3. sigset_t4. 信号集操作函数sigprocmasksigpendingsignal测试这几个系统调用接口 进程地址空间第三讲捕捉信号1. 内核如何实现信号的捕捉2. siga…

一个能够自我游戏的贪吃蛇(pygame与搜索算法)

贪吃蛇小游戏再经典不过了,作为编程爱好者,代码编译的贪吃蛇,又能有怎样的成绩呢? 带着好奇,开始! 先做一个普通的贪吃蛇游戏 引入相关package import pygame 定义相关配置变量 # 定义字体 font pyg…

SQLiteC/C++接口详细介绍之sqlite3类(十六)

返回目录:SQLite—免费开源数据库系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(十五) 下一篇: SQLiteC/C接口详细介绍之sqlite3类(十七)(未发表) 50.sqlite…

STL:List从0到1

🎉个人名片: 🐼作者简介:一名乐于分享在学习道路上收获的大二在校生 🙈个人主页🎉:GOTXX 🐼个人WeChat:ILXOXVJE 🐼本文由GOTXX原创,首发CSDN&…

uniapp开发微信小程序调用打电话

在使用uniapp开发微信小程序的时候&#xff0c;经常需要调用打电话功能。 下面我们来讲解一下如何实现该功能&#xff0c;效果图请看下图&#xff1a; 代码部分&#xff1a; <!-- h5部分 --><button click"playphone()"></button><!-- JS部分 …

代码随想录day21(1)二叉树:平衡二叉树(leetcode110)

题目要求&#xff1a;判断一棵树是否为平衡二叉树 思路&#xff1a;递归地比较左右子树&#xff0c;只要有一棵子树不满足条件就说明这棵树不是平衡二叉树。本题采用迭代法较为复杂。 leetcode实战&#xff1a; 代码实现&#xff1a; 递归&#xff1a; 迭代&#xff1a;

【WebAssembly】WebAssembly概念介绍和在js中使用

简言 记录下WebAssembly的概念和在JavaScript中的使用方法。 WebAssembly官网 WebAssembly WebAssembly &#xff08;缩写为 Wasm&#xff09;是一种二进制指令格式&#xff0c;用于基于堆栈的虚拟机。Wasm 被设计为编程语言的可移植编译目标&#xff0c;可在网络上部署客户…

爬虫逆向sm3和sm4 加密 案例

注意&#xff01;&#xff01;&#xff01;&#xff01;某XX网站逆向实例仅作为学习案例&#xff0c;禁止其他个人以及团体做谋利用途&#xff01;&#xff01;&#xff01; 案例--aHR0cDovLzExMS41Ni4xNDIuMTM6MTgwODgvc3Vic2lkeU9wZW4 第一步&#xff1a;分析页面和请求方式 …

代码随想录算法训练营第39天 | 62.不同路径 , 63. 不同路径 II

动态规划章节理论基础&#xff1a; https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 62.不同路径 题目链接&#xff1a;https://leetcode.cn/problems/unique-paths/ 思路&#xff1a; 动规五部曲&#xff1a…

实战Python Socket编程:开发多用户聊天应用

实战Python Socket编程&#xff1a;开发多用户聊天应用 Python Socket 编程概述什么是Socket编程&#xff1f;Socket编程的应用场景Socket编程的重要性基本概念 环境准备Python版本必要的库开发环境配置调试工具 基本Socket编程创建Socket绑定Socket到端口监听连接接受连接发送…

基于C++的反射功能

需求&#xff1a; 利用C的发射机制&#xff0c;实现根据字符串创建实例对象。 代码&#xff1a; #ifndef OBJECT_H #define OBJECT_H#include <string> #include <map>typedef void* (*Constructor)();class CObjectFactory { public:static void registerClass…

Spring Boot轻松整合Minio实现文件上传下载功能【建议收藏】

一、Linux 安装Minio 安装 在/root/xxkfz/soft目录下面创建文件minio文件夹&#xff0c;进入minio文件夹&#xff0c;并创建data目录&#xff1b; [rootxxkfz soft]# mkdir minio [rootxxkfz soft]# cd minio [rootxxkfz minio]# mkdir data执行如下命令进行下载 [rootxxkf…

python基础——字符串的常见操作方法【下标索引,index,count,len,replace,split,strip】

&#x1f4dd;前言&#xff1a; 字符串是一种有序的&#xff0c;允许重复字符串存在的&#xff0c;不可修改的序列 这篇文章主要总结一下python中有关字符串的部分相关知识&#xff0c;以及字符串的常见操作方法&#xff1a; 1&#xff0c;和其他序列极其类似的操作方法 2&…

Three 材质纹理 (总结三)

THREE.MeshLambertMaterial&#xff08;网格 Lambert 材质&#xff09; 该材质使用基于非物理的Lambertian模型来计算反射率。可以用来创建暗淡的并不光亮的表面&#xff0c;该材质非常易用&#xff0c;而且会与场景中的光源产生反应。 MeshLambertMaterial属性 # .color : …

mysql中用逗号隔开的某字段,如何判断其他表的字段值是否在这个字段中

因为要增加需求&#xff0c;需要将线上表中老数据&#xff0c;修改为新数据的规则。 线上两张表&#xff0c;sequence_number中is_use有3作废、2到期状态&#xff0c;需要根据这个状态和school_ai_authorization中的is_deleted修改新增的state字段。 sequence_number表结构&…