12 | 架构案例:基于OAuth 2.0/JWT的微服务参考架构

news2025/3/1 22:16:50

12 | 架构案例:基于OAuth 2.0/JWT的微服务参考架构

架构图
image.png

  1. 令牌的校验和转换,将前端传递过来的 OAuth 2.0 访问令牌,通过调用 IDP 进行校验,并转换为包含用户和权限信息的 JWT 令牌,再将 JWT 令牌向后台微服务传递。
  2. 权限校验,网关的路由表可以和 OAuth 2.0 的 Scope 进行关联。这样,网关根据请求令牌中的权限范围 Scope,就可以判断请求是否具有调用后台服务的权限。

IDP 服务:IDP 是 Identity Provider 的简称,主要负责 OAuth 2.0 授权协议处理,OAuth 2.0 和 JWT 令牌颁发和管理,以及用户认证等功能。IDP 使用后台的 Login-Service 进行用户认证。
BFF 层:主要实现对后台领域服务的聚合(Aggregation,有点类似数据库的 Join)功能,同时为不同的前端体验(PC/Mobile/ 开放平台等)提供更友好的 API 和数据格式。
领域服务层:领域服务层在整个微服务架构的底层。这些服务包含业务逻辑,通常有自己独立的数据库存储,还可以根据需要调用外部的服务。

场景 1:第一方 Web 应用 + 资源拥有者凭据模式

image.png

  1. 用户通过浏览器访问 ACME 公司的电商网站,点击登录链接。
  2. Web 应用返回登录界面(这个登录页可以是网站自己定制开发)。
  3. 用户输入用户名、密码进行认证。
  4. Web 应用将用户名、密码,通过网关转发到 IDP 的令牌获取端点(POST /oauth2/token,grant_type=password)。
  5. IDP 通过 Login Service 对用户进行认证。
  6. IDP 认证通过,返回有效访问令牌(根据需要也可以返回刷新令牌)。
  7. Web 应用接收到访问令牌,创建用户 Session,并将 OAuth 2.0 令牌保存其中,然后返回登录成功到用户端。
  8. 用户浏览器中记录 Session Cookie,登录成功。

认证授权之后的服务调用流程
image.png

  1. 用户登录后,在网站上点击查看自己的购物历史记录。
  2. Web 应用通过网关调用后台 API(查询用户的购物历史记录),请求 HTTP header 中带上 OAuth 2.0 令牌(来自用户 Session)。
  3. 网关截取 OAuth 2.0 令牌,去 IDP 进行校验。
  4. IDP 校验令牌通过,再通过令牌查询用户和 Scope 信息,构建 JWT 令牌,返回。
  5. 网关获得 JWT 令牌,校验 Scope 是否有权限调用 API,如果有就转发到后台 API 进行调用。
  6. 后台 BFF(或者领域服务)通过传递过来的 JWT 获取用户信息,根据用户 ID 查询购物历史记录,返回。
  7. Web 应用获得用户的购物历史数据,可以根据需要缓存在 Session 中,再返回用户端。
  8. 购物历史数据返回到用户浏览器端。

场景 2:第一方移动应用 + 授权码许可模式

image.png

  1. 用户访问电商 App,点击登录。
  2. App 生成 PKCE 相关的 code verifier + challenge。
  3. App 以内嵌方式启动手机浏览器,访问 IDP 的统一认证页 (GET /authorize),请求带上 PKCE 的 code challenge 相关参数。
  4. IDP 返回统一认证页。
  5. 用户认证和授权。
  6. IDP 通过 Login Service 对用户进行认证。
  7. IDP 返回授权码到 App 浏览器。
  8. App 截取浏览器带回的授权码,将授权码 +PKCE code verifer,通过网关转发到 IDP 的令牌获取端点(POST /oauth2/token, grant_type=authorization-code)。
  9. IDP 校验 PKCE 和授权码,校验通过则返回有效访问令牌。
  10. App 获取令牌,本地存储,登录成功。

场景 3:第三方 Web 应用 + 授权码模式

image.png

  1. 用户访问这个第三方 Web 应用,点击登录链接。
  2. Web 应用后台向 ACME 公司的 IDP 服务发送申请授权码请求(GET /authorize)。
  3. 用户被重定向到 ACME 公司的 IDP 统一登录页面。
  4. 用户进行认证和授权。
  5. IDP 通过 Login Service 对用户进行认证。
  6. 认证和授权通过,IDP 返回授权码。
  7. Web 应用获得授权码,再向 IDP 服务的令牌获取端点发起请求(POST /oauth2/token, grant_type=authorization-code)。
  8. IDP 校验授权码,校验通过则返回有效 OAuth 2.0 令牌(根据需要也可以返回刷新令牌)。
  9. Web 应用创建用户 Session,将 OAuth 2.0 令牌保存在 Session 中,然后返回登录成功到用户端。
  10. 用户浏览器中记录 Session Cookie,登录成功。

额外说几点
第一点是,IDP 的 API 要支持从 OAuth 2.0 访问令牌到 JWT 令牌的互转。今天我们提到的集成架构采用 OAuth 2.0 访问令牌 + JWT 令牌的混合模式,中间需要实现 OAuth 2.0 访问令牌到 JWT 令牌的互转。这个互转 API 并非 OAuth 2.0 的标准,有些 IDP 产品(比方 Spring Security OAuth)可能并不支持,因此需要用户定制扩展。
第二点是**,关于单页 SPA 应用场景**。关于单页 SPA 应用场景,简单做法是采用隐式许可,但是这个模式是 OAuth 2.0 中比较不安全的,
第三点是,关于 SSO 单点登录场景。为了简化描述,上面的流程没有考虑 SSO 单点登录场景。如果要支持 Web SSO,那么各种应用场景都必须通过浏览器 +IDP 登录页集中登录,并且 IDP 要支持 Session,用于维护登录态。如果 IDP 以集群方式部署的话,还要考虑粘性 Sticky Session 或者集中式 Session。
第四点是关于 IDP 和网关的部署方式。前面的几张架构图中,IDP 虽然躲在网关后面,但实际上 IDP 可以直接通过 Nginx 对外暴露,不经过网关。或者,IDP 的登录授权页面,可以通过 Nginx 直接暴露,API 接口则走网关。
第五点是关于刷新令牌。为了简化描述,上面的流程没有详细说明刷新令牌的集成方式。企业根据场景需要,可以启用刷新令牌,来延长用户的登录时间,具体的集成方式需要考虑安全性的需求。
第六点是关于 Web Session。为了简化描述,在上面的流程中,Web 应用登录成功后假设启用 Web Session,也就是服务器端 Session。在实际场景中,Web Session 并非唯一选择,也可以采用简单的客户端 Session 方式,也称无状态 Session,也就是在客户端浏览器 Cookie 中保存 OAuth 2.0 访问令牌。

全程使用oauth2令牌,那么网关之后的每个微服务都需要自己根据令牌token去idp或者redis或者mysql中去查询用户信息,如果全程使用jwt令牌,主要是还是由于jwt自包含用户信息,存在暴露用户信息的安全风险。(如果jwt中只存在用户名,不存在其他相关信息也可以考虑全程使用jwt令牌)

原文

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

New Bing乘上ChatGPT的东风,日活突破1亿

我是卢松松,点点上面的头像,欢迎关注我哦! 注:本文由松松杰哥缮写,ChatGPT进行了补充和润色,你们可以看看本文和其他文有什么区别? 微软今天宣布,New Bing乘上ChatGPT的东风&#xf…

【设计模式】中介者模式和观察者模式

中介者模式 中介模式的英⽂翻译是 Mediator Design Pattern。 在 GoF 中的《设计模式》⼀书中,它是这样定义的: Mediator pattern defines a separate (mediator) object that encapsulates the interaction between a set of objects and the objects …

C#:Krypton控件使用方法详解(第十五讲) ——kryptonBorderEdge

今天介绍的Krypton控件中的kryptonBorderEdge。下面介绍控件的外观属性如下图所示:Cursor属性:表示鼠标移动过该控件的时候,鼠标显示的形状。属性值如下图所示:UseWaitCursor属性:表示鼠标在控件中等待时,以…

大学模拟电路期末考试模拟题详解

(一)选择题 3.4.5.6.7.8.9.10. (二)填空题 1.漂流电流是温度电流,它由少数、载流子形成、其大小与温度有关,而与外加电压无关。 反向电流是由少数载流子形成、其大小与温度有关,而与外加电压无…

AOP通知类型:

AOP通知类型: 环绕通知无参与ProceedingJoinPoint接口:方法的前后进行环绕,但是与before和after不同的是,他无法知道下面代码中的环绕前方法是否是在前置位置,后置同理,于是要在方法中添加参数ProceedingJo…

Android之事件机制

Android之事件机制MotionEvent事件的分发与处理触屏事件的类型触摸事件发生的位置触摸事件的分发和处理用于分发和处理的方法事件分发和处理的过程KeyEvent参考MotionEvent事件的分发与处理 在我们日常使用app的时候会进行各种各样的触摸操作,比如点击、长按等&…

谈一谈搜索引擎是如何跟踪你、出卖你的

文章目录跟踪结果点击跟踪关键词跟踪other跟踪 结果点击跟踪 以b网为例,当我们搜索关键词“haha”后,搜索结果链接是这样子的: https://www.baidu.com/link?urlX02KNEaEhaHM-7eY_i6OWGWBZ9_KEYvIlMec91jStRWvcg4uyumrhdefe-ZzdrLKk7iewh9a…

pycharm专业版安装_教育邮箱

怎样安装pycharm专业版? 专业版与社区版的区别 二者区别很多,笔者主要看中了远程连接这个功能。下面讲解怎样使用教育邮箱免费获取专业版pcharm。 1.获取免费的利license (1)进入pycharm官方网站,链接为&#xff1…

小米数据恢复:有无备份从小米手机恢复删除数据方法

如果您不小心删除了小米手机上的数据,后来发现您需要它,那么本文适合您。我将向您介绍一些最可靠的小米恢复方法,以将您的数据恢复到您的设备上。无论您是否有备份,都可以处理。让我们开始吧! 小米数据恢复 - 如何做&a…

vue打包后用docker镜像部署

vue3项目打包成dist后,用Dockerfile,镜像部署。后在线上运行。 我在阿里云买了个轻量服务器。系统镜像是centos7。现在Linux下安装Docker。 比如我打包好的dist文件夹,要和Dockorfile在同一级目录下,不然在build构建时是找不到d…

第十届省赛——9等差数列(集合做法)

题目:试题 I: 等差数列时间限制: 1.0s 内存限制: 512.0MB 本题总分:25 分【问题描述】数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列,只记得其中 N 个整数。现在给出这 N 个整数,小明想知道包含这…

推荐系统中对抗性机器学习-文献综述与未来发展整理分享

对抗学习是一种机器学习技术,旨在通过提供欺骗性输入来欺骗模型。最常见的原因是导致机器学习模型出现故障。大多数机器学习技术旨在处理特定的问题集,其中从相同的统计分布(IID)生成训练和测试数据。当这些模型应用于现实世界时&…

【数据库】聊聊MySQL的日志,binlog、undo log、redo log

日志 在数据库中,如何保证数据的回滚,以及数据同步,系统宕机后可以恢复到原来的状态,其实就是依靠日志。 其中bin log是Server层特有的,redo log是Innodb存储引擎特有的。 bin log 是逻辑日志,主要记录这条…

Win11安装Docker

一、进入Docker官网首先先到Docker官网下载最新官方Docker for Windows链接:Docker下载在官网内可以查看到Docker的开发文档:根据官网提示,Windows环境下下载Docker必须满足:Docker for Windows requires 64bit Windows 11 Pro an…

0311记录

题目1:B. Not Dividing 这个题有点奇怪,他的大意就是给定一个数组,可以对数组中的任意一个数做+1操作,保证a(i1)不被a(i)整除,但是总次数不能超过2*n 感觉这就是一个结论吧,就是随便加&#xff…

CSS看这一篇就够啦,CSS基础大全,可用于快速回顾知识,面试首选

1 CSS简介 CSS 是层叠样式表 ( Cascading Style Sheets ) 的简称。 CSS 是也是一种标记语言,主要用于设置 HTML 页面中的文本内容(字体、大小、对齐方式等)、图片的外形(宽高、边框样式、 边距等)以及版面的布局和外观…

【Linux】linux | 修改系统编码 |  增加字体处理 | 图片处理字体变成方块

一、说明1、CentOS7二、修改系统编码编辑文件vi /etc/locale.conf修改编码并保存LANGzh_CN.UTF-8配置生效source /etc/locale.conf1)修改系统编码,只是让系统支持中文编码2)不解决文字不显示的问题;往后看三、解决字体不显示问题非…

【玩转c++】priority_queue的介绍和模拟实现

本期主题:priority_queue的介绍和模拟实现博客主页: 小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限,出现错误希望大家不吝赐priority_queue介绍和使用1.1.priority_queue介绍1. 优先队列是一种容器适配器,根…

数组边遍历(for循环)边删除为什么删不干净 及三种实现删除的方法

文章目录1、为什么删不干净倒序删迭代器lambda表达式删除为什么说数组边for循环遍历边删除会出现删不干净的情况1、为什么删不干净 先写一个例子:可以先猜一下控制台会打印出什么内容? public class removeIterator {public static void main(String[]…

Node.js 里 Express工程框架中的代码解析

新建一个工程 express -e blog配置入口文件 打开项目内的app.js ,在倒数第二行写入如下代码: app.listen(3000, function () {console.log(server is running in 3000) })这样就让服务运行在了3000端口 检查 打开终端输入: node app在打开浏览器访…