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…

ubuntu 硬盘扩容

在 Linux 中&#xff0c;可以使用以下命令查看磁盘的使用情况和信息&#xff1a; 查看磁盘使用情况&#xff1a; df -h这个命令会显示所有文件系统的使用情况&#xff0c;以人类可读的格式&#xff08;例如 GB 或 MB&#xff09;。 查看磁盘分区和设备信息&#xff1a; lsblk这…

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.…

练习题 - Scrapy爬虫框架 Requests and Responses 请求和响应

Scrapy 是一个用于在 Python 中构建网络爬虫和抓取数据的强大工具。对于学习网络爬虫的编程初学者来说,了解 Scrapy 的请求(Requests)和响应(Responses)机制至关重要。这些机制不仅是 Scrapy 工作的核心,也是理解如何与网页进行交互的关键。 通过这篇文章,我们将通过实…

gitlab 的备份与回复

一、gitlab备份 1.确定备份目录 gitlab 默认的备份目录为/var/opt/gitlab/backups&#xff0c;可通过配置gitlab.rb配置文件进行修改&#xff0c;如&#xff1a; [rootlocalhost ~]# vim /etc/gitlab/gitlab.rb #若要修改备份文件的存储目录话&#xff0c;打开下面选项的注释…

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

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

基于去哪儿旅游出行服务平台旅游推荐网站【源码+安装+讲解+售后+文档】

【1】系统介绍 研究背景 随着互联网技术的飞速发展和移动互联网的普及&#xff0c;人们的旅游消费习惯发生了显著变化。在线旅游服务逐渐成为人们计划旅行、预订酒店、机票以及制定行程的主要方式之一。去哪儿网作为国内领先的在线旅游平台之一&#xff0c;通过整合众多旅游资…

提升数据处理效率: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;将一些经验沉淀在…

【鼠鼠学AI代码合集#8和9】线性神经网络

深度学习中的矢量化加速 在深度学习模型的训练过程中&#xff0c;处理大量数据的效率对模型性能至关重要。为此&#xff0c;我们通常希望能够在一次操作中处理整个小批量的样本&#xff0c;而不是逐一处理每个样本。这种优化方式称为矢量化。通过矢量化&#xff0c;我们可以充…

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

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

C++学习笔记----9、发现继承的技巧(六)---- 有趣且令人迷惑的继承问题(2)

2、给继承类添加虚基类成员函数的重载 给继承类添加新的虚基类成员函数的重载是可能的。也就是说&#xff0c;可以用新的原型给继承类中的虚成员函数添加重载&#xff0c;但是继续继承基类版本。这个技术使用了using声明来显式包含了继承类中的成员函数的基类定义。下面为示例&…

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

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