spring gateway网关接口黑名单实现

1. 背景

灵活配置线上接口黑名单,可以临时调用

2. 网关路由配置application.yml

server:port: 8868
spring:cloud:gateway:globalcors: # 全局的跨域配置add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题# options请求 就是一种询问服务器是否浏览器可以跨域的请求# 如果每次跨域都有询问服务器是否浏览器可以跨域对性能也是损耗# 可以配置本次跨域检测的有效期maxAge# 在maxAge设置的时间范围内,不去询问,统统允许跨域corsConfigurations:'[/**]':allowedOriginPatterns: # 允许哪些网站的跨域请求- "*"allowedMethods: # 允许的跨域ajax的请求方式- "GET"- "POST"- "DELETE"- "PUT"- "OPTIONS"allowedHeaders: "*"    # 允许在请求中携带的头信息allowCredentials: true    # 允许在请求中携带cookiemaxAge: 360000            # 本次跨域检测的有效期(单位毫秒)# 有效期内,跨域请求不会一直发option请求去增大服务器压力routes: # 网关路由配置- id: route_to_provider #service服务,业务逻辑uri: lb://cloud-k8s-enterprise-service #通过服务发现找到 Service 服务predicates:- Path=/pay/**,/wx/callback/**- id: route_to_server #web服务 入口uri: lb://cloud-k8s-enterprise-server #通过服务发现找到 Service 服务predicates:- Path=/**#default-filters:# - name: BlacklistFilter#BlacklistFilter 在 default-filters 中使用时可能导致了错误。default-filters 是一个全局过滤器的配置,通常这些过滤器需要是 Spring Cloud Gateway 提供的预定义过滤器,而不是自定义的全局过滤器。你的 BlacklistFilter 是自定义的全局过滤器,不能直接放在 default-filters 中。
logging:level:org.springframework.cloud.gateway: DEBUG

2.1. 坑点:无法进行路由转发,配置格式;无法加载自定义全局过滤器

spring.cloud.gateway: 注意坑点!!!!!!!

这里如果单独把nacos配置拎出去,注释了,结果网关路由gateway缺少cloud这层配置,一直无法进行路由转发,网关配置未生效

server:
  port: 8868
spring:
#  application:
#    name: service-gateway
#  cloud:  注意坑点!!!!!!! 这里有人单独把nacos配置拎出去,注释了,结果网关路由gateway缺少cloud这层配置,一直无法进行路由转发,网关配置未生效
#    nacos:
#      discovery:
#        server-addr: 127.0.0.1:8848
    gateway:
      globalcors: # 全局的跨域配置

default-filters:

- name: BlacklistFilter

BlacklistFilter 在 default-filters 中使用时可能导致了错误。default-filters 是一个全局过滤器的配置,通常这些过滤器需要是 Spring Cloud Gateway 提供的预定义过滤器,而不是自定义的全局过滤器。你的 BlacklistFilter 是自定义的全局过滤器,不能直接放在 default-filters 中。

可以配置在某个单独的服务下

#单服务黑名单网关配置demo
spring:cloud:gateway:routes:- id: dynamic_blacklist_routeuri: http://localhost:8080predicates:- Path=/api/v1/**filters:- name: BlacklistFilter
server:port: 8868
spring:
#  application:
#    name: service-gateway
#  cloud:  注意坑点!!!!!!! 这里有人单独把nacos配置拎出去,注释了,结果网关路由gateway缺少cloud这层配置,一直无法进行路由转发,网关配置未生效
#    nacos:
#      discovery:
#        server-addr: 127.0.0.1:8848gateway:globalcors: # 全局的跨域配置add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题# options请求 就是一种询问服务器是否浏览器可以跨域的请求# 如果每次跨域都有询问服务器是否浏览器可以跨域对性能也是损耗# 可以配置本次跨域检测的有效期maxAge# 在maxAge设置的时间范围内,不去询问,统统允许跨域corsConfigurations:'[/**]':allowedOriginPatterns: # 允许哪些网站的跨域请求- "*"allowedMethods: # 允许的跨域ajax的请求方式- "GET"- "POST"- "DELETE"- "PUT"- "OPTIONS"allowedHeaders: "*"    # 允许在请求中携带的头信息allowCredentials: true    # 允许在请求中携带cookiemaxAge: 360000            # 本次跨域检测的有效期(单位毫秒)# 有效期内,跨域请求不会一直发option请求去增大服务器压力routes: # 网关路由配置- id: route_to_provider #service服务,业务逻辑uri: lb://cloud-service #通过服务发现找到 Service 服务predicates:- Path=/apiv1/**,/apiv2/**- id: route_to_server #web服务 入口uri: lb://cloud-server #通过服务发现找到 Service 服务predicates:- Path=/**
logging:level:org.springframework.cloud.gateway: DEBUG

2.2. 帮助文档

Spring Colud gateway 网关引入转发无效 (404)_gateway_虔浅-云原生

跟着大佬们的文章,想玩一下gateway api网关。经过一系列ctrl+c和ctrl+v的操作,项目的基本就搭建好了;

1.引入依赖 pom.xml

<!--网关依赖-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--不要引入web!不要引入web!不要引入web!gateway中已经包含-->

2.创建启动类

//如果有注册机(nacos,eureka)什么的可以不用引入
//@EnableDiscoveryClient,只需在配置文件里面配置好就行
@SpringBootApplication
public class GatewayServer {public static void main(String[] args) {SpringApplication.run(GatewayServer.class,args);}
}

3.配置文件

server:port: 9999                    #服务端口spring:application:name: gateway      #服务名称cloud:############# nacos配置中心 start (没有注册机可以不用配置这一块) #############nacos:# nacos配置中心    #nacos的配置文件名称(Data Id)叫 服务名称.yml ,# 组名(Group)config:server-addr: http://nacos服务器file-extension: ymlnamespace: xxx #命名空间(md5)group: 分组名    #分组#发现配置discovery:server-addr: http://www.lang9725.fun/find/namespace:  xxx #命名空间(md5)group: batw############# nacos配置中心 end ########################### 网关配置 start ##############gateway:#开启网关,和很多地方说不一样,很多地方都是这个是默认开启的,#但设置的话网关功能将无效enabled: trueroutes:- id: server_finance        #id 唯一即可uri: http://localhost:44444  #用转发路径predicates:- Path=/test/test/**     # **表示转发地址下的全部都可以通过 ############## 网关配置 end ##############

这里要一个被转发服务器地址: http://localhost:44444/test/test/任意地址 并保证这个地址没问题,我们的测试网关地址:http://localhost:9999/test/test/任意地址,保证两个地址的返回效果一致(负载均衡效果到达预期)

前期没有配置spring.cloud.gateway.enabled=true,测试网关一直到报404,看了很多大佬debug,不明所以,最后发现是这边配置没有加,而是配置一个spring.cloud.gateway.discovery.locator.enabled=true,后面加了spring.cloud.gateway.enabled=true就可以了,这个东西应该是和版本,和依赖包一定联系吧。

3. nacos配置bootstrap.yml

spring: #springboot的配置application:name: cloud-gatewaycloud:nacos:config:server-addr: 127.0.0.1:8848namespace: cloud-localfile-extension: ymlshared-configs:- data-id: blacklist.yml # 在 Nacos 中的配置 Data IDrefresh: true           # 启用动态刷新discovery:server-addr: 127.0.0.1:8848namespace: cloud-local 

4. 黑名单配置blacklist.yml

blacklist:paths:- /coupon/manualGrantPowerCard- /coupon/manualGrantVoucher

4.1. 加载配置类BlacklistConfig.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;import java.util.List;/*** @author shenlifang* @since 黑名单配置类* @date 2024/10/21 11:16*/
@Component
@RefreshScope
@ConfigurationProperties(prefix = "blacklist")
public class BlacklistConfig {private List<String> paths;// Getter 和 Setterpublic List<String> getPaths() {return paths;}public void setPaths(List<String> paths) {this.paths = paths;}
}

5. 启动类,扫描包GatewayApplication.java


import com.ly.cloud.gateway.config.BlacklistConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigurationProperties(BlacklistConfig.class)
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);}
}

6. 自定义全局过滤器BlacklistFilter.java

package com.cloud.gateway.config;import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.nio.charset.StandardCharsets;
import java.util.List;/*** @author shenlifang* @date 2024/10/21 11:12* @since 接口黑名单过滤器*/
@Component
public class BlacklistFilter implements GlobalFilter, Ordered {// 黑名单接口路径列表,可以通过配置文件或者数据库来动态管理private final BlacklistConfig blacklistConfig;// 通过构造器注入 BlacklistConfigpublic BlacklistFilter(BlacklistConfig blacklistConfig) {this.blacklistConfig = blacklistConfig;}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String path = exchange.getRequest().getURI().getPath();// 获取配置中的黑名单路径List<String> blacklistedPaths = blacklistConfig.getPaths();// 检查请求路径是否在黑名单中if (isBlacklistedPath(path, blacklistedPaths)) {// 如果匹配黑名单,返回 403 Forbiddenexchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);// return exchange.getResponse().setComplete();// 设置响应头,表示内容类型为 JSONexchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);// 返回描述信息// String responseBody = "{\"successful\":false,\"code\":403,\"message\":\"接口服务禁用: 该接口服务已加入黑名单,禁止访问!\"}";String responseBody = "{\"error\": \"Access denied: The requested path is blacklisted.\"}";// 写入响应体DataBufferFactory bufferFactory = exchange.getResponse().bufferFactory();DataBuffer buffer = bufferFactory.wrap(responseBody.getBytes(StandardCharsets.UTF_8));// 完成响应return exchange.getResponse().writeWith(Mono.just(buffer));}// 如果没有匹配黑名单,继续执行后续过滤器链return chain.filter(exchange);}// 判断路径是否在黑名单中private boolean isBlacklistedPath(String path, List<String> blacklistedPaths) {return blacklistedPaths.stream().anyMatch(path::startsWith);}@Overridepublic int getOrder() {return -1;}
}

7. 优化改造:优先从redis中获取

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.List;
import java.util.concurrent.TimeUnit;@Component
public class BlacklistFilter implements GlobalFilter, Ordered {private final BlacklistConfig blacklistConfig;private final RedisTemplate<String, List<String>> redisTemplate;// 通过构造器注入 BlacklistConfig 和 RedisTemplatepublic BlacklistFilter(BlacklistConfig blacklistConfig, RedisTemplate<String, List<String>> redisTemplate) {this.blacklistConfig = blacklistConfig;this.redisTemplate = redisTemplate;}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String path = exchange.getRequest().getURI().getPath();// 优先从 Redis 中获取黑名单路径List<String> blacklistedPaths = redisTemplate.opsForValue().get("blacklist_paths");// 如果 Redis 中没有黑名单路径,则从配置文件中获取并缓存到 Redisif (blacklistedPaths == null || blacklistedPaths.isEmpty()) {blacklistedPaths = blacklistConfig.getPaths();// 将配置文件中的黑名单缓存到 Redis,有效期设置为 10 分钟redisTemplate.opsForValue().set("blacklist_paths", blacklistedPaths, 10, TimeUnit.MINUTES);}// 检查请求路径是否在黑名单中if (isBlacklistedPath(path, blacklistedPaths)) {// 如果匹配黑名单,返回 403 Forbiddenexchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);return exchange.getResponse().setComplete();}// 如果没有匹配黑名单,继续执行后续过滤器链return chain.filter(exchange);}// 判断路径是否在黑名单中private boolean isBlacklistedPath(String path, List<String> blacklistedPaths) {return blacklistedPaths.stream().anyMatch(path::startsWith);}@Overridepublic int getOrder() {return -1;}
}

8. 网关启动过程中日志打印网关配置属性

如果没打印,查看yaml文件配置是否有问题

2024-10-21 17:14:02.677 DEBUG 8754 --- [ main] o.s.c.gateway.config.GatewayProperties : Routes supplied from Gateway Properties: [RouteDefinition{id='route_to_provider', predicates=[PredicateDefinition{name='Path', args={_genkey_0=/apiv1/**, _genkey_1=/apiv2/**}}], filters=[], uri=lb://cloud-service, order=0, metadata={}}, RouteDefinition{id='route_to_server', predicates=[PredicateDefinition{name='Path', args={_genkey_0=/**}}], filters=[], uri=lb://cloud-server, order=0, metadata={}}]

日志中的 o.s.c.gateway.config.GatewayProperties 是 Spring Cloud Gateway 在启动过程中输出的日志。具体解释如下:

  • o.s.c.gateway.config.GatewayProperties:这是类的名称,表示 org.springframework.cloud.gateway.config.GatewayProperties。这个类负责管理 Spring Cloud Gateway 的配置属性,包括网关的路由、过滤器等信息。
  • Routes supplied from Gateway Properties::这条日志表明,Spring Cloud Gateway 已经从应用的配置文件(例如 application.yml 或者 bootstrap.yml)中读取并加载了路由配置。

  • RouteDefinition:表示每一条路由定义。
    • id:路由的唯一标识符,例如 route_to_providerroute_to_server
    • predicates:路由谓词,用来匹配请求路径。例如,Path 谓词匹配 /apiv1/**/apiv2/** 等路径。
    • filters:表示应用在路由上的过滤器,在当前配置中为空(没有应用额外的过滤器)。
    • uri:目标 URI,lb://cloud-service 表示通过负载均衡(LoadBalancer)转发请求到服务 cloud-service
    • order:路由的优先级,值越小优先级越高。
    • metadata:存储路由的元数据,当前为空。

Spring Cloud Gateway 从配置文件中正确读取并加载了两个路由定义,分别是 route_to_providerroute_to_server,并根据配置的路径规则(Path)匹配请求并进行转发。

如果路由匹配不正确,可以通过查看这些日志确认路由是否如预期加载。

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

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

相关文章

2024最新IOS应用商店下载页源码 支持一键跳转设置双端app

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 支持apk&#xff0c;ipa&#xff0c;ios描述文件上传分发下载网站自适应PC手机自适应&#xff08;适配市面上主流手机&#xff0c;包括安卓和苹果&#xff09;支持引导用户正确使用浏…

Go:error处理机制

文章目录 本篇总结的是Go中对于错误的处理机制 Go 语言的函数经常使用两个返回值来表示执行是否成功&#xff1a;返回某个值以及 true 表示成功&#xff1b;返回零值&#xff08;或 nil&#xff09;和 false 表示失败 而实际上来说&#xff0c;是需要对于第二个参数进行判断的…

物流管理系统设计与实现

摘 要 本物流管理系统是针对目前物流管理系统管理的实际需求&#xff0c;从实际工作出发&#xff0c;对过去的物流管理系统管理系统存在的问题进行分析&#xff0c;结合计算机系统的结构、概念、模型、原理、方法&#xff0c;在计算机各种优势的情况下&#xff0c;采用目前jsp…

Cocos Creator导出obj文件用于后端寻路

Cocos Creator 3.8.0 用这个扩展插件 【杨宗宝】两年前写的网格工具&#xff0c;今天将它开源了。 - Creator 3.x - Cocos中文社区carlosyzy_extensions_mesh: Cocos Creator 3.x mesh插件&#xff0c;负责网格数据的导出。合并&#xff0c;拆封等一系列操作 (gitee.com) 下…

基于vue框架的的地铁站智慧管理系统的设计n09jb(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,上班打卡,下班打卡,人员管理,交接班,视频巡检,车辆巡检,车辆管理 开题报告内容 基于Vue框架的地铁站智慧管理系统的设计开题报告 一、研究背景与意义 随着城市化进程的加速&#xff0c;地铁站作为城市交通系统的重要组成部分&am…

C#学习笔记(九)

C#学习笔记&#xff08;九&#xff09; 第六章 面向对象编程&#xff08;一&#xff09;类与对象、字段与属性一、类与对象正确的理解1. 什么是类&#xff1f;2.什么是对象&#xff1f;3. 类与对象的区别 二、类的基本规范和对象使用1. 类的规范 三、类的访问修饰符&#xff08…

Jsoup在Java中:解析京东网站数据

对于电商网站如京东来说&#xff0c;其页面上的数据包含了丰富的商业洞察。对于开发者而言&#xff0c;能够从这些网站中提取有价值的信息&#xff0c;进行分析和应用&#xff0c;无疑是一项重要的技能。本文将介绍如何使用Java中的Jsoup库来解析京东网站的数据。 Jsoup简介 …

开源表单生成器OpnForm

什么是 OpnForm &#xff1f; OpnForm 是一个开源的表单构建工具&#xff0c;旨在简化创建自定义表单的过程&#xff0c;特别适合无编码知识的用户。它通过人工智能优化表单创建流程&#xff0c;支持多种用途&#xff0c;如联系人表单、调查表等。OpnForm 提供了一个直观的拖放…

Oracle Form开发遇到的一些问题

1.错误&#xff1a;FRM-32083: Value length is too long for maximum length of item. 解决&#xff1a;Maximum Length要设置的大些。 2.问题&#xff1a;FRM-30047: Cannot resolve item reference RATEPAYER_INFO.PARTY_SITE_ID. 解决&#xff1a;该引用使用错误&#xff…

图片写入GPS经纬高信息

近期项目中需要往java平台传输图片&#xff0c;直接使用QNetworkAccessManager和QHttpMultipart类即可&#xff0c;其他博文中有分享。 主要是平台接口对所传输图片有要求&#xff1a;需要包含GPS信息&#xff08;经度、纬度、高度&#xff09;。 Qt无法直接实现&#xff0c;…

优先级队列(2)_数据流中第k大元素

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 优先级队列(2)_数据流中第k大元素 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目…

深度解析机器学习的四大核心功能:分类、回归、聚类与降维

深度解析机器学习的四大核心功能&#xff1a;分类、回归、聚类与降维 前言分类&#xff08;Classification&#xff09;&#xff1a;预测离散标签的艺术关键算法与代码示例逻辑回归支持向量机&#xff08;SVM&#xff09; 回归&#xff08;Regression&#xff09;&#xff1a;预…

信息学奥赛复赛复习18-CSP-J2022-01解密-二分答案、二分找边界、二分时间复杂度、二分求最小

PDF文档回复:20241017 1 P8814 [CSP-J 2022] 解密 [题目描述] 给定一个正整数 k&#xff0c;有 k 次询问&#xff0c;每次给定三个正整数 ni,ei,di&#xff0c;求两个正整数 pi,qi&#xff0c;使 nipiqi、eidi(pi−1)(qi−1)1 [输入格式] 第一行一个正整数 k&#xff0c;表…

Docker 入门 - 拉取/创建镜像 + 运行和管理容器

写在前面&#xff1a; 本篇简单介绍一下如何入手 Docker&#xff0c;从 创建/拉取 镜像&#xff0c;再到运行和管理容器&#xff0c;还包括导出容器等操作。这里先贴一下官方的文档地址&#xff1a; Docker DocsDocker Documentation is the official Docker library of reso…

在Windows系统中,cmd 查看 MongoDB 相关信息

MongoDB是一种流行的NoSQL数据库&#xff0c;广泛应用于各种现代应用程序中。 1 查看MongoDB的版本号 要查看MongoDB的版本号&#xff0c;可以使用mongo命令连接到MongoDB&#xff0c;然后执行db.version()。 mongo连接到数据库后&#xff0c;执行以下命令&#xff0c;输出M…

java如何部署web后端服务

java如何部署web后端服务 简单记录一下&#xff0c;方便后续使用。 部署流程 1.web打包 2.关掉需要升级的运行中的服务 /microservice/hedgingcustomer-0.0.1-SNAPSHOT/conf/bin/ 执行脚本 sh shutdown.sh 3.解压文件 返回到/microservice 将升级包上传到该路径&#x…

10款超好用的文档加密软件|2024企业常用文档加密软件排行榜!

在当今的数字化时代&#xff0c;企业的数据安全已经成为了一项至关重要的任务。为了确保企业核心信息资产的安全性和完整性&#xff0c;越来越多的企业开始采用文档加密软件。以下是2024年企业常用的10款超好用的文档加密软件排行榜。 1. Ping32文档加密软件 Ping32是一款功能…

重磅发布,Wireshark 4.4.1 修复多个漏洞,性能新升级

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 中午好&#xff0c;我的网工朋友 Wireshark 一直以其强大的数据包捕获和分析功能而闻名。作为网络工程师、安全分析师和开发者的重要工具&#x…

Java项目-基于spingboot框架的校友社交系统系统项目实战(附源码+文档)

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

中石化万总经理一行莅临点赋科技公司考察调研

近日&#xff0c;中石化万总经理一行莅临点赋科技公司&#xff0c;进行了坦诚而富有成效的交流&#xff0c;双方在轻松而又热烈的氛围中&#xff0c;逐步达成了初步合作意向。 在参观过程中&#xff0c;点赋科技董事长崔梦姣详细介绍了公司的发展历程、核心技术以及未来的发展规…