java脚手架系列9-统一权限认证gateway

之所以想写这一系列,是因为之前工作过程中有几次项目是从零开始搭建的,而且项目涉及的内容还不少。在这过程中,遇到了很多棘手的非业务问题,在不断实践过程中慢慢积累出一些基本的实践经验,认为这些与业务无关的基本的实践经验其实可以复刻到其它项目上,在行业内可能称为脚手架,因此决定将此java基础脚手架的搭建总结下来,分享给大家使用。

注意由于框架不同版本改造会有些使用的不同,因此本次系列中主要使用基本框架是 spring-boo-2.3.12.RELEASE和spring-cloud.-Hoxton.SR12,所有代码都在commonFramework项目上:https://github.com/forever1986/commonFramework/tree/master

目录

  • 1 gateway
  • 2 动态加载路由表
  • 3 鉴权功能

1 gateway

之所以将gateway放在这里讲,是因为承接上一篇的OAuth2,其中gateway有一个重要的功能就是鉴权,可以结合OAuth2进行鉴权。
在我们使用微服务架构的时候,免不了需要一个网关,而对于java项目来说,gateway是一个很好的选择。一般实践中,gateway有以下功能:

  • 路由转发:根据请求的特定条件(如 URL路径、请求参数、请求头等)来将请求转发到后端的多个服务,并支持动态路由配置
  • 过滤功能:提供了一套过滤器机制,允许开发人员对请求进行修改和验证,以及应用各种策略,如认证、安全、监控/指标、限流、日志、请求转发/重试等
  • 容错处理:集成断路器(Hystrix),为微服务网关提供容错处理的功能
  • 服务发现:与服务注册中心集成,动态从服务注册中心获取服务信息并进行路由
  • 请求转发:进行请求的协议转换,比如将 HTTP 请求转换成 WebSocket 请求
  • 请求限流:支持通过配置限流规则,对请求进行限流,防止恶意请求或异常情况下的流量冲击

下面以动态读取路由配置+过滤功能,实现gateway的路由转发可以动态加载,以及实现鉴权功能

2 动态加载路由表

参考gateway子模块

在实际应用中,我们不可能将路由配置放入项目的yaml配置文件中,这样修改路由时,都需要重新启动或者发布。这时候,配置中心就起到动态配置路由转发的存储功能,同时gateway也提供RouteDefinitionRepository可进行路由表动态加载。

原理:将路由配置文件放入nacos中,gateway子模块通过实现RouteDefinitionRepository,监听nacos的路由配置文件,实现动态更新路由配置

1)创建gateway子模块,引入以下依赖:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--监听配置文件的更新 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--获取配置文件 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

2)配置bootstrap.yml,要配置服务发现和配置中心的信息

server:port: 9991
spring:application:name: cloud-gateway-servicecloud:nacos:discovery:server-addr: 127.0.0.1:8848username: nacospassword: nacosconfig:server-addr: 127.0.0.1:8848username: nacospassword: nacosfile-extension: yamlgroup: DEFAULT_GROUPprefix: ${spring.application.name}

3)实现NacosRouteDefinitionRepository(实现RouteDefinitionRepository),用于自动监听配置文件并刷新路由表

package com.demo.route.config;import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;/*** nacos路由数据源*/
@Component
public class NacosRouteDefinitionRepository implements RouteDefinitionRepository {private static final Logger logger = LoggerFactory.getLogger(NacosRouteDefinitionRepository.class);private static final String SCG_DATA_ID = "cloud-gateway-service";private static final String SCG_GROUP_ID = "DEFAULT_GROUP";private final ApplicationEventPublisher publisher;private final NacosConfigManager nacosConfigManager;public NacosRouteDefinitionRepository(ApplicationEventPublisher publisher, NacosConfigManager nacosConfigManager) {this.publisher = publisher;this.nacosConfigManager = nacosConfigManager;addListener();}@Overridepublic Flux<RouteDefinition> getRouteDefinitions() {List<RouteDefinition> routeDefinitionList = new ArrayList<>(0);try {String configContent = nacosConfigManager.getConfigService().getConfig(SCG_DATA_ID, SCG_GROUP_ID, 5000);if (StringUtils.isNotEmpty(configContent)) {routeDefinitionList = JSON.parseArray(configContent, RouteDefinition.class);}} catch (NacosException e) {logger.error("从Nacos加载配置的动态路由信息异常", e);}return Flux.fromIterable(routeDefinitionList);}/*** 添加Nacos监听*/private void addListener() {try {nacosConfigManager.getConfigService().addListener(SCG_DATA_ID, SCG_GROUP_ID, new Listener() {@Overridepublic Executor getExecutor() {return null;}@Overridepublic void receiveConfigInfo(String configInfo) {publisher.publishEvent(new RefreshRoutesEvent(this));}});} catch (NacosException e) {logger.error("添加Nacos监听异常", e);}}@Overridepublic Mono<Void> save(Mono<RouteDefinition> route) {return null;}@Overridepublic Mono<Void> delete(Mono<String> routeId) {return null;}
}

4)设置GatewayApplication设置@EnableDiscoveryClient注册到nacos
5)在nacos的public命名空间和DEFAULT_GROUP分组中,配置nacos的路由配置名为:cloud-gateway-service的json文件

[{"id": "baidu","order": 0,"predicates": [{"args": {"pattern": "/baidu/**"},"name": "Path"}],"uri": "http://www.baidu.com","filters": [{"args": {"_genkey_0": "2"},"name": "StripPrefix"}]},{"id": "manager","predicates": [{"args": {"pattern": "/manager/**"},"name": "Path"}],"uri": "http://localhost:9981","filters": [{"args": {"_genkey_0": "1"},"name": "StripPrefix"}]}
]

6)通过请求以下访问,可以得到转发;同时你可以在nacos上面修改cloud-gateway-service的json文件路由,可以测试动态刷新
http://localhost:8891/baidu/aa
http://localhost:8891/business/business

3 鉴权功能

参考gateway子模块

网关的过滤功能:提供了一套过滤器机制,允许开发人员对请求进行修改和验证,以及应用各种策略,如认证、安全、监控/指标、限流、日志、请求转发/重试等。我们这里的鉴权就是使用过滤功能。在配置鉴权功能之前,我们有必要了解一下内容:

  • 鉴权原理:在系列8中我们讲过security、JWT、oauth的内容,这里利用auth-authentication子模块生成token,我们知道验证token的有效性2种方法,一种是使用访问auth-authentication子模块的access_token接口验证,一种是通过RSA非对称加密验证。这里的token采用RSA非对称加密验证(这是因为本身路由访问非常频繁的服务,不适合频繁访问access_token接口)。
  • gateway过滤:在gateway中有3个比较重要的过滤:ReactiveAuthenticationManager->ReactiveAuthorizationManager->Gateway Filters。

1)其中ReactiveAuthenticationManager用于封装JWT为OAuth2Authentication并判断Token的有效性;
2)ReactiveAuthorizationManager用于基于URL的鉴权;
3)Gateway Filters是网关的过滤流程。

下面我们通过配置JWT+RSA的解密对token进行认证,另外通过实现ReactiveAuthorizationManager对其进行鉴权。
1)引入以下依赖:

<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId>
</dependency>
<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-oauth2-resource-server</artifactId>
</dependency>
<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-oauth2-jose</artifactId>
</dependency>

3)编写ResourceServerManager(实现ReactiveAuthorizationManager),实现其check接口,获得用户信息,对权限进行判断(这里只是演示一下,没有实际权限判断代码,实际业务中可以加入一些权限判断,比如路由权限、RABC等业务判断功能)
4)编写ResourceServerConfig,通过注入securityWebFilterChain类,将JWT认证和ResourceServerManager都设置到过滤链中
5)在ResourceServerConfig中,通过注入jwtAuthenticationConverter,实现JWT+RSA的公钥,对token进行认证
6)编写SecurityGlobalFilter(实现GlobalFilter,和Ordered),做最后处理(当然如果没有此需求,也可以不做处理)
7)通过请求以下访问,可以得到转发(前提是你需要在header中增加token)
http://localhost:8891/baidu/aa
http://localhost:8891/business/business

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

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

相关文章

[大模型学习推理]资料

https://juejin.cn/post/7353963878541361192 lancedb是个不错的数据库&#xff0c;有很多学习资料 https://github.com/lancedb/vectordb-recipes/tree/main/tutorials/Multi-Head-RAG-from-Scratch 博主讲了很多讲解&#xff0c;可以参考 https://juejin.cn/post/7362789…

JMeter详细介绍和相关概念

JMeter是一款开源的、强大的、用于进行性能测试和功能测试的Java应用程序。 本篇承接上一篇 JMeter快速入门示例 &#xff0c; 对该篇中出现的相关概念进行详细介绍。 JMeter测试计划 测试计划名称和注释&#xff1a;整个测试脚本保存的名称&#xff0c;以及对该测试计划的注…

【原创】统信UOS如何安装最新版Node.js(20.x)

注意直接使用sudo apt install nodejs命令安装十有八九会预装10.x的老旧版本Node.js&#xff0c;如果已经安装的建议删除后安装如下方法重装。 在统信UOS系统中更新Node.js可以通过以下步骤进行&#xff1a; 1. 卸载当前版本的Node.js 首先&#xff0c;如果系统中已经安装了N…

4.1.2 网页设计技术

文章目录 1. 万维网&#xff08;WWW&#xff09;的诞生2. 移动互联网的崛起3. 网页三剑客&#xff1a;HTML、CSS和JavaScriptHTML&#xff1a;网页的骨架CSS&#xff1a;网页的外衣JavaScript&#xff1a;网页的活力 4. 前端框架的演变基于CSS的框架基于JavaScript的框架基于MV…

【Django】继承框架中用户模型基类AbstractUser扩展系统用户表字段

Django项目新建好app之后&#xff0c;通常情况下需要首要考虑的就是可以认为最重要的用户表&#xff0c;即users对应的model&#xff0c;它对于系统来说可以说是最基础的依赖。 实际上&#xff0c;我们在初始进行migration的时候已经同步生成了相应的user表&#xff0c;如下&am…

spygalss cdc 检测的bug(二)

当allow_qualifier_merge设置为strict的时候&#xff0c;sg是要检查门的极性的。 如果qualifier和src经过与门汇聚&#xff0c;在同另一个src1信号或门汇聚&#xff0c;sg是报unsync的。 假设当qualifier为0时&#xff0c;0&&src||src1src1&#xff0c;src1无法被gat…

xss-labs靶场第十七关测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、注入点寻找 2、使用hackbar进行payload测试 3、绕过结果 四、源代码分析 五、结论 一、测试环境 1、系统环境 渗透机&#xff1a;本机(127.0.0.1) 靶 机&#xff1a;本机(127.0.0.…

Jenkins发布vue项目,版本不一致导致build错误

问题一 yarn.lock文件的存在导致在自动化的时候&#xff0c;频频失败问题二 仓库下载的资源与项目资源版本不一致 本地跑好久的一个项目&#xff0c;现在需要部署在Jenkins上面进行自动化打包部署&#xff1b;想着部署后今后可以省下好多时间&#xff0c;遂兴高采烈地去部署&am…

提升数据处理效率:TDengine S3 的最佳实践与应用

在当今数据驱动的时代&#xff0c;如何高效地存储与处理海量数据成为了企业面临的一大挑战。为了解决这一问题&#xff0c;我们在 TDengine 3.2.2.0 首次发布了企业级功能 S3 存储。这一功能经历多个版本的迭代与完善后&#xff0c;逐渐发展成为一个全面和高效的解决方案。 S3…

python 实现一个简单的浏览器引擎

1. 浏览器引擎工作原理 浏览器引擎是用来处理、渲染和显示网页内容的核心组件。其主要任务是将用户输入的URL所代表的网页资源加载并呈现出来&#xff0c;通常包括HTML、CSS、JavaScript以及各种多媒体内容。浏览器引擎的工作原理可以分为以下几个主要步骤&#xff1a; 1.1 U…

软件系统建设方案书(word参考模板)

1 引言 1.1 编写目的 1.2 项目概述 1.3 名词解释 2 项目背景 3 业务分析 3.1 业务需求 3.2 业务需求分析与解决思路 3.3 数据需求分析【可选】 4 项目建设总体规划【可选】 4.1 系统定位【可选】 4.2 系统建设规划 5 建设目标 5.1 总体目标 5.2 分阶段目标【可选】 5.2.1 业务目…

FlinkSQL之temporary join开发

在实时开发中&#xff0c;双流join获取目标对应时刻的属性时&#xff0c;经常使用temporary join。笔者在流量升级的实时迭代中&#xff0c;需要让流量日志精准的匹配上浏览时间里对应的商品属性&#xff0c;使用temporary join开发过程中踩坑不少&#xff0c;将一些经验沉淀在…

【开源免费】基于SpringBoot+Vue.JS网上超市系统(JAVA毕业设计)

本文项目编号 T 037 &#xff0c;文末自助获取源码 \color{red}{T037&#xff0c;文末自助获取源码} T037&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

研发运营一体化(DevOps)能力成熟度模型

目录 应用设计 安全风险管理 技术运 持续交付 敏捷开发管理 基于微服务的端到端持续交付流水线案例 应用设计 安全风险管理 技术运 持续交付

Android 判断手机放置的方向

#1024程序员节&#xff5c;征文# 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 需求 老板&#xff1a;我有个手持终端&#xff0c;不能让他倒了&#xff0c;当他倒或者倾斜的时候要发出报警&#xff1b; 程序猿&#xff1a;我这..... 老板…

2024-09-28 地址空间与进程控制

一、进程地址空间 Pt.2 同一个变量&#xff0c;地址相同&#xff0c;其实是虚拟地址相同&#xff0c;内容不同其实是被映射到了不同的物理地址 1. 页表 内存保护与页表标志位 在操作系统中&#xff0c;页表用于管理内存的访问权限。每个页表项通常包含一组标志位&…

二:Python学习笔记--基础知识(1) 变量,关键字,数据类型,赋值运算符,比较运算符

目录 1. 变量 2. python关键字 3. python数据类型 3.1 数字类型 整型 int 浮点型 float 内置函数-type 3.2 字符串类型 3.3 布尔类型 3.4 空类型 3.5 列表类型 3.6 元组类型 3.7 字典类型 4. python赋值运算 5. python比较运算符 1. 变量 组成&#xff1a;必须是数…

基于SSM的BBS社区论坛系统源码

运行环境&#xff1a;ideamysql5.7jdk8maven 使用技术&#xff1a;ssmmysqlshirolayui 功能模块&#xff1a;用户管理、模板管理、帖子管理、公告管理、权限管理等

yolov9目标检测/分割预测报错AttributeError: ‘list‘ object has no attribute ‘device‘常见汇总

这篇文章主要是对yolov9目标检测和目标分割预测测试时的报错&#xff0c;进行解决方案。 在说明解决方案前&#xff0c;严重投诉、吐槽一些博主发的一些文章&#xff0c;压根没用的解决方法&#xff0c;也不知道他们从哪里抄的&#xff0c;误人子弟、浪费时间。 我在解决前&…

Lampiao靶机入侵实战

07-Lampiao靶机入侵实战 一、扫描采集信息 1、获取IP地址 nmap -sn 192.168.81.0/24获得IP地址为&#xff1a;192.168.81.1282、获取端口信息 由于nmap默认情况下只扫描常用的1000个端口&#xff0c;覆盖面并不全&#xff0c;所以建议全端口扫描 nmap -p 1-65535 192.168.…