当前位置: 首页 > news >正文

【Oauth2整合gateway网关实现微服务单点登录】

文章目录

    • 一.什么是单点登录?
    • 二.Oauth2整合网关实现微服务单点登录
    • 三.时序图
    • 四.代码实现思路
      • 1.基于OAuth2独立一个认证中心服务出来
      • 2.网关微服务
      • 3产品微服务
      • 4.订单微服务
      • 5.开始测试单点登录

一.什么是单点登录?

单点登录(Single Sign On),简称为 SSO,是比较流行的企业业务整合的解决方案之一。它的用途在于,不管多么复杂的应用群,只要在用户权限范围内,那么就可以做到用户只需要登录一次就可以访问权限范围内的所有应用子系统。

二.Oauth2整合网关实现微服务单点登录

网关整合 OAuth2.0 有两种思路:

  • 一种是授权服务器生成令牌, 所有请求统一在网关层验证,判断权限等操作;
  • 另一种是由各资源服务处理,网关只做请求转发。

比较常用的是第一种,把API网关作为OAuth2.0的资源服务器角色,实现接入客户端权限拦截、令牌解析并转发当前登录用户信息给微服务,这样下游微服务就不需要关心令牌格式解析以及OAuth2.0相关机制了。

网关在认证授权体系里主要负责两件事:
(1)作为OAuth2.0的资源服务器角色,实现接入方权限拦截。
(2)令牌解析并转发当前登录用户信息(明文token)给微服务

微服务拿到明文token(明文token中包含登录用户的身份和权限信息)后也需要做两件事:
(1)用户授权拦截(看当前用户是否有权访问该资源)
(2)将用户信息存储进当前线程上下文(有利于后续业务逻辑随时获取当前用户信息)

三.时序图

在这里插入图片描述

四.代码实现思路

1.基于OAuth2独立一个认证中心服务出来

  • 启动OAuth2认证授权中心:需要定义配置类重新AuthorizationServerConfigurerAdapter认证服务配置适配器类的3个configure方法。
    以及需要用到spring-security的WebSecurityConfigurerAdapter类等等,这里不贴代码了,只讲思路。
  • 比如我认证中心服务配置完,端口启动为:8888。

2.网关微服务

我们要自定义认证过滤器。认证过滤器里面需要做:

  1. 获取请求头里面的token信息
  2. 然后传入参数token信息通过rpc调用认证服务 http://auth-server/oauth/check_token进行token认证。
    也可以定义授权过滤器:进行token信息里面的自定义权限校验等等,需要使用@Order(1)注解,值越小优先级越高,指定这个过滤器在认证过滤器之后。
  3. 然后向下游业务系统传递解析后的token信息。

我启动端口为:8880,下面是认证过滤器核心代码:

/*** 认证过滤器*/
@Component
@Order(0)
public class AuthenticationFilter implements GlobalFilter, InitializingBean {@Autowiredprivate RestTemplate restTemplate;private static Set<String> shouldSkipUrl = new LinkedHashSet<>();@Overridepublic void afterPropertiesSet() throws Exception {// 不拦截认证的请求shouldSkipUrl.add("/oauth/token");shouldSkipUrl.add("/oauth/check_token");shouldSkipUrl.add("/user/getCurrentUser");}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String requestPath = exchange.getRequest().getURI().getPath();//不需要认证的urlif(shouldSkip(requestPath)) {return chain.filter(exchange);}//获取请求头String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization");//请求头为空if(StringUtils.isEmpty(authHeader)) {throw new RuntimeException("请求头为空");}TokenInfo tokenInfo=null;try {//获取token信息tokenInfo = getTokenInfo(authHeader);}catch (Exception e) {throw new RuntimeException("校验令牌异常");}// tokenInfoexchange.getAttributes().put("tokenInfo",tokenInfo);return chain.filter(exchange);}private boolean shouldSkip(String reqPath) {for(String skipPath:shouldSkipUrl) {if(reqPath.contains(skipPath)) {return true;}}return false;}private TokenInfo getTokenInfo(String authHeader) {// 往授权服务发请求 /oauth/check_token// 获取token的值String token = StringUtils.substringAfter(authHeader, "bearer ");HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);//必须 basicAuth clienId clientSecretheaders.setBasicAuth(MDA.clientId, MDA.clientSecret);MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("token", token);HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);ResponseEntity<TokenInfo> response = restTemplate.exchange(MDA.checkTokenUrl, HttpMethod.POST, entity, TokenInfo.class);return response.getBody();}
}

常量类:

public class MDA {public static final String clientId = "gateway-server";public static final String clientSecret = "123123";public static final String checkTokenUrl = "http://auth-server/oauth/check_token";}

3产品微服务

我启动端口为:8084

4.订单微服务

我启动端口为:8082

5.开始测试单点登录

  1. 比如哪个单点登录接口处理完业务相关逻辑等,然后请求我们的授权服务-通过密码模式获取到access_token
    在这里插入图片描述
  2. 使用同一access_token,请求网关获取订单信息
    在这里插入图片描述
    3.使用同一access_token,请求网关获取商品信息
    在这里插入图片描述
    这样就完成我们的单点登录啦。

相关文章:

【Oauth2整合gateway网关实现微服务单点登录】

文章目录 一.什么是单点登录&#xff1f;二.Oauth2整合网关实现微服务单点登录三.时序图四.代码实现思路1.基于OAuth2独立一个认证中心服务出来2.网关微服务3产品微服务4.订单微服务5.开始测试单点登录 一.什么是单点登录&#xff1f; 单点登录&#xff08;Single Sign On&…...

WEB领域是不是黄了还是没黄

进入2024年后&#xff0c;WEB领域大批老表失业&#xff0c;一片哀嚎&#xff0c;个个饿的鬼叫狼嚎&#xff0c;为啥呢&#xff0c;下面是我个人的见解和看法。 中国程序员在应用层的集中 市场需求&#xff1a;中国的互联网行业在过去几年中经历了爆炸性增长&#xff0c;尤其是…...

Android系统:系统架构

文章目录 分层设计分块设计总结 分层设计 自上而下分为&#xff1a;应用层、应用架构层、系统运行层、硬件抽象层、Linux内核层 应用层 封装一系列系统App 应用架构层(Framework) 封装一系列运行App需要的Java框架 提供App开发需要的API 系统运行层(Libraries) 封装一系…...

NCNN 源码(1)-模型加载-数据预处理-模型推理

参考 ncnn 第一个版本的代码。 0 整体流程 demo&#xff1a;squeezenet ncnn 自带的一个经典 demo&#xff1a;squeezenet 的代码: // 网络加载 ncnn::Net squeezenet; squeezenet.load_param("squeezenet_v1.1.param"); squeezenet.load_model("squeezenet_…...

重修设计模式-结构型-享元模式

重修设计模式-结构型-享元模式 复用不可变对象&#xff0c;节省内存 享元模式&#xff08;Flyweight Pattern&#xff09;核心思想是通过共享对象方式&#xff0c;达到节省内存和提高性能的目的。享元对象需是不可变对象&#xff0c;因为它会被多处代码共享使用&#xff0c;要避…...

JavaScript 运算符

JavaScript 中的运算符可以根据其功能和用途分为几类。以下是主要的运算符类型及其用法&#xff1a; 1. 算术运算符 用于执行基本的数学运算。 : 加法 let sum 5 3; // 8- : 减法 let difference 5 - 3; // 2* : 乘法 let product 5 * 3; // 15/ : 除法 let quotient 5…...

3.js - 运动曲线

这个球&#xff0c;绕着这个红色的线圈转 代码 import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControlslet scene,camera,renderer,controls nulllet moon,earth null// 根据&#xff0c;一系列的点&#xff0c;创建曲线 le…...

免费ppt模板哪里找?职场必备这些利器

一眨眼&#xff0c;9月份的尾声渐近&#xff0c;无论是学生还是职场人士&#xff0c;都开始准备着新一轮的演讲和报告。在这个忙碌的时期&#xff0c;一份精美的PPT模板能够大幅提升你的工作效率&#xff0c;让你的演示更加引人入胜。 不用担心高昂的版权费用&#xff0c;市场…...

wampserve 配置本地域名,出现错误

概述 今天更换了电脑&#xff0c;在本地安装和配置docker的时候&#xff0c;想用自定义域名访问NGINX容器&#xff0c;127.0.0.1和localhost都可以访问&#xff0c;但是自定义域名无法访问&#xff0c; 接着去捯饬已经使用的wampserver的集成环境&#xff0c;出现了同样的问题…...

MySQL慢查询优化指南

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 前言 当遇到慢查询问题时&#xff0c;不仅影响服务效率&#xff0c;还可能成为系统瓶颈。作为一位软件工程师&#xff0c;掌握MySQL慢查询优化技巧至关重要。今天&#xff0c;我们就来一场“数据库加速之旅…...

怎么录制游戏视频?精选5款游戏录屏软件

对于热爱游戏的你来说&#xff0c;记录游戏中的精彩瞬间并分享给朋友或粉丝&#xff0c;无疑是一种享受。然而&#xff0c;在众多录屏软件中&#xff0c;如何选择最适合你的那一款&#xff1f;今天&#xff0c;我们就为大家精选了五款游戏录屏软件&#xff0c;需要的朋友快来选…...

论文阅读 - MDFEND: Multi-domain Fake News Detection

https://arxiv.org/pdf/2201.00987 目录 ABSTRACT INTRODUCTION 2 RELATED WORK 3 WEIBO21: A NEW DATASET FOR MFND 3.1 Data Collection 3.2 Domain Annotation 4 MDFEND: MULTI-DOMAIN FAKE NEWS DETECTION MODEL 4.1 Representation Extraction 4.2 Domain Gate 4.…...

LabVIEW软件出现Bug如何解决

在LabVIEW开发中&#xff0c;程序出现bug是不可避免的。无论是小型项目还是复杂系统&#xff0c;调试与修复bug都是开发过程中的重要环节。下文介绍如何有效解决LabVIEW软件中的bug&#xff0c;包括常见错误类型、调试工具、错误处理机制。 1. 常见Bug类型分析 在LabVIEW中&am…...

【数据结构-栈】力扣844. 比较含退格的字符串

给定 s 和 t 两个字符串&#xff0c;当它们分别被输入到空白的文本编辑器后&#xff0c;如果两者相等&#xff0c;返回 true 。# 代表退格字符。 注意&#xff1a;如果对空文本输入退格字符&#xff0c;文本继续为空。 示例 1&#xff1a; 输入&#xff1a;s “ab#c”, t “…...

DataFrame生成excel后为什么多了一行数字

问题描述 python查询数据生成excel文件&#xff0c;生成的excel多了第一行数字索引&#xff0c;1,2,3,4,5...... 代码&#xff1a; df pd.DataFrame(data)df.to_excel(filename, sheet_name用户信息表, indexFalse) 解决&#xff1a; 原理也很简单&#xff0c;就是设置个参…...

linux 内存屏障(barrier)分析

谈起内存屏障,大家感觉这个"玩意儿"很虚,不太实际,但是内核代码中又广泛地可以看到起身影。内存屏障,英文barrier,这个"玩意儿"它还不太好去定义它。barrier,中文翻译为栅栏&#xff0c;栅栏大家都见过,现实生活中就是防止他人或者动物非法闯入而用来进行隔…...

【人工智能】Transformers之Pipeline(十九):文生文(text2text-generation)

目录 一、引言 二、文生文&#xff08;text2text-generation&#xff09; 2.1 概述 2.2 Flan-T5: One Model for ALL Tasks 2.3 pipeline参数 2.3.1 pipeline对象实例化参数 2.3.2 pipeline对象使用参数 ​​​​​​​ 2.3.3 pipeline返回参数 ​​​​​​​​​​​…...

如何使用ssm实现基于VUE的儿童教育网站的设计与实现+vue

TOC ssm676基于VUE的儿童教育网站的设计与实现vue 第一章 课题背景及研究内容 1.1 课题背景 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全…...

MODBUS TCP 转 CANOpen

产品概述 SG-TCP-COE-210 网关可以实现将 CANOpen 接口设备连接到 MODBUS TCP 网络中。用户不需要了解具体的 CANOpen 和 Modbus TCP 协议即可实现将CANOpen 设备挂载到 MODBUS TCP 接口的 PLC 上&#xff0c;并和 CANOpen 设备进行数据交互。 产品特点 &#xf…...

vue2+elementUI实现handleSelectionChange批量删除-前后端

功能需求&#xff1a;实现选中一个或多个执行批量删除操作 在elementUI官网选择一个表格样式模板&#xff0c;Element - The worlds most popular Vue UI framework 这里采用的是 将代码复制到前端&#xff0c;这里是index.vue <template><el-button type"dang…...

LLMs之OCR:llm_aided_ocr(基于LLM辅助的OCR项目)的简介、安装和使用方法、案例应用之详细攻略

LLMs之OCR&#xff1a;llm_aided_ocr(基于LLM辅助的OCR项目)的简介、安装和使用方法、案例应用之详细攻略 目录 llm_aided_ocr的简介 1、特性 2、详细技术概览 PDF处理和OCR PDF到图像转换 OCR处理 文本处理流程 分块创建 错误校正与格式化 重复内容移除 标题和页码…...

低代码平台后端搭建-阶段完结

前言 最近又要开始为跳槽做准备了&#xff0c;发现还是写博客学的效率高点&#xff0c;在总结其他技术栈之前准备先把这个专题小完结一波。在这一篇中我又试着添加了一些实际项目中可能会用到的功能点&#xff0c;用来验证这个平台的扩展性&#xff0c;以及总结一些学过的知识。…...

暑假考研集训营游记

文章目录 摘要&#xff1a;1.对各大辅导机构考研封闭集训营的一些个人看法&#xff1a;2.对于考研原因一些感想&#xff1a;结语 摘要&#xff1a; Ashy在暑假的时候参加了所在辅导班的为期一个月的考研封闭集训营&#xff0c;有了一些全新的感悟&#xff0c;略作记录。 1.对…...

C#中的报文(Message)

在C#中&#xff0c;报文&#xff08;Message&#xff09;通常是指在网络通信中交换的数据单元。报文可以由多种不同的组成部分构成&#xff0c;具体取决于通信协议和应用场景。 以下是一些常见的报文组成部分&#xff1a; 头部&#xff08;Header&#xff09;&#xff1a;包含…...

Python知识点:如何使用Python与Java进行互操作(Jython)

开篇&#xff0c;先说一个好消息&#xff0c;截止到2025年1月1日前&#xff0c;翻到文末找到我&#xff0c;赠送定制版的开题报告和任务书&#xff0c;先到先得&#xff01;过期不候&#xff01; Jython 是一种完全兼容 Java 的 Python 实现&#xff0c;它将 Python 代码编译成…...

ffmpeg解封装解码

文章目录 封装和解封装封装解封装 相关接口解封装的流程图关于AVPacket的解释如何区分不同的码流&#xff0c;视频流&#xff0c;音频流&#xff1f;第一种方式av_find_best_stream第二种方式 通过遍历流 代码 封装和解封装 封装 是把音频流 &#xff0c;视频流&#xff0c;字…...

golang学习笔记10-循环结构

注&#xff1a;本人已有C&#xff0c;C,Python基础&#xff0c;只写本人认为的重点。 go的循环只有for循环&#xff0c;但有多个语法&#xff0c;可以实现C/C中的while和do while。当然&#xff0c;for循环也有break和continue&#xff0c;这点和C/C相同。 语法1&#xff1a; f…...

Java高级编程——泛型(泛型类、泛型接口、泛型方法,完成详解,并附有案例+代码)

文章目录 泛型21.1 概述21.2 泛型类21.3 泛型方法21.4 泛型接口 泛型 21.1 概述 JDK5中引入的特性&#xff0c;在编译阶段约束操作的数据类型&#xff0c;并进行检查 泛型格式&#xff1a;<数据类型> 泛型只能支持引用数据类型&#xff0c;如果写基本数据类型需要写对…...

GPU硬件如何实现光栅化?

版权声明 本文为“优梦创客”原创文章&#xff0c;您可以自由转载&#xff0c;但必须加入完整的版权声明文章内容不得删减、修改、演绎本文视频版本&#xff1a;见文末 引言 大家好&#xff0c;我是老雷&#xff0c;今天我想从GPU硬件原理出发&#xff0c;给大家分享在图形渲…...

Python写入文件内容:从入门到精通

在日常编程工作中&#xff0c;我们常常会遇到需要将数据保存至磁盘的需求。无论是日志记录、配置文件管理还是数据持久化&#xff0c;掌握如何有效地使用Python来写入文件内容都是必不可少的一项技能。本文将从基础语法开始&#xff0c;逐步深入探讨Python中写入文件内容的各种…...