微服务-gateway鉴权

文章目录

  • 一、前言
  • 二、gateway鉴权
    • 1、依赖配置
    • 2、编写代码
    • 3、GlobalFilter详解
      • 3.1、GlobalFilter简介
      • 3.2、GlobalFilter自定义执行顺序
      • 3.2.1、实现Order接口实现自定义执行顺序

一、前言

网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过 网关这一层。也就是说,API 的实现方面更多的考虑业务逻辑,而安全、性能、监控可以交由 网关来做,这样既提高业务灵活性又不缺安全性。

RBAC基于角色访问控制,目前使用最为广泛的权限模型。相信大家对这种权限模型已经比较了解了。此模型有三个用户、角色和权限,在传统的权限模型用户直接关联加了角色,解耦了用户和权限,使得权限系统有了更清晰的职责划分和更高的灵活度

二、gateway鉴权

在这里插入图片描述

1、依赖配置

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--redis-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--json-->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version>
</dependency>

2、编写代码

@Order(1)
@Component
public class AuthorizationFilter implements GlobalFilter {@Autowiredprivate AuthConfig myConfig;@Autowiredprivate AuthService authService;@Autowiredprivate RedisUtil redisUtil;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpResponse response = exchange.getResponse();JSONObject message = new JSONObject();ServerHttpRequest request = exchange.getRequest();//1、获取请求路径String path = request.getPath().toString();//处理白名单内不需要进行拦截的地址if(!Objects.isNull(myConfig.getWhiteList())){for (String whitePath : myConfig.getWhiteList()) {if(path.contains(whitePath)){return chain.filter(exchange);}}}//获取对应的tokenString token = request.getHeaders().getFirst("Authorization");//判断传递了token才可以继续解析if(!StringUtils.isEmpty(token)){try {//先去本地redis根据token获取valueString userPhoneRedis = redisUtil.getTokenKey(token);//如果没有查到,或者过期时间小于10分钟,则去权限获取信息,权限会进行token续约if (Objects.isNull(userPhoneRedis) || redisUtil.getExpire(userPhoneRedis) < 600) {String userId=authService.checkToken(token);//如果校验token成功if(null!=userId){//缓存到redis中,一段时间内都不用校验token了//token为key,用户id为value,存储7200秒(2小时)redisUtil.set(token,userId,7200);//放行继续向下调用return chain.filter(exchange);}}else{return chain.filter(exchange);//放行继续向下调用}}catch (Exception e){//拦截请求,返回状态码401message.put("status", -1);message.put("data", "鉴权失败");byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);DataBuffer buffer = response.bufferFactory().wrap(bits);response.setStatusCode(HttpStatus.UNAUTHORIZED);//指定编码,否则在浏览器中会中文乱码response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");return response.writeWith(Mono.just(buffer));}}message.put("status", -1);message.put("data", "鉴权失败");byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);DataBuffer buffer = response.bufferFactory().wrap(bits);response.setStatusCode(HttpStatus.UNAUTHORIZED);//指定编码,否则在浏览器中会中文乱码response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");return response.writeWith(Mono.just(buffer));}
}

3、GlobalFilter详解

3.1、GlobalFilter简介

GlobalFilter是Spring Cloud Gateway中用于过滤请求的组件,它可以在请求与路由匹配时,将所有的GlobalFilter和特定的GatewayFilter添加到过滤器链中,然后按照org.springframework.core.Ordered接口排序执行。

GlobalFilter具有与GatewayFilter相同的签名,因此可以在处理请求之前和之后执行一些操作,例如检查请求头、修改请求参数、验证权限等。在实现GlobalFilter接口时,需要实现filter方法,该方法接受一个WebExchange作为参数。

在Spring Cloud Gateway中,有一些默认的GlobalFilter,例如ForwardRoutingFilter和RouteToRequestUrlFilter,它们分别用于将请求转发到当前网关实例本地接口和将请求路由到指定的URL。

当请求与路由匹配时,过滤web处理程序会将GlobalFilter的所有实例和GatewayFilter的所有路由特定实例添加到过滤器链中。这个组合过滤器链由org.springframework.core.Ordered接口排序,您可以通过实现getOrder()方法来设置该接口,值越小,越先执行。由于Spring Cloud Gateway区分了过滤器逻辑执行的“pre”和“post”阶段,优先级最高的过滤器是“pre”阶段的第一个,“post”的最后一个。

3.2、GlobalFilter自定义执行顺序

在gateway模块中有多个GlobalFilter时,你可以通过实现Ordered接口,或者使用@Order注解来指定每个GlobalFilter的执行顺序。order值越小,优先级越高,执行顺序越靠前。

如果多个GlobalFilter的order值一样,会按照默认的顺序执行,这个默认顺序是:defaultFilter > 路由过滤器 > GlobalFilter。
在这里插入图片描述
在这里插入图片描述
例如,在我的网关模块中,有两个自定义的GlobalFilter,一个用于做跨域处理,一个用户做权限鉴权,我们需要指定它们的执行顺序,优先应该走权限鉴权的,假如你都没有权限去请求服务,那么就不需要再去考虑当前请求是否跨域了。以上图片展示是通过@Order的方式实现的GlobalFilter自定义执行顺序;

3.2.1、实现Order接口实现自定义执行顺序

import org.springframework.cloud.gateway.filter.GlobalFilter;  
import org.springframework.cloud.gateway.filter.GatewayFilterChain;  
import org.springframework.core.Ordered;  
import org.springframework.stereotype.Component;  
import org.springframework.web.server.ServerWebExchange;  
import reactor.core.publisher.Mono;  @Component  
public class CustomGlobalFilter implements GlobalFilter, Ordered {  @Override  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {  // 在请求处理之前执行一些操作  // ...  // 继续执行下一个过滤器或路由处理程序  return chain.filter(exchange);  }  @Override  public int getOrder() {  // 返回该过滤器的优先级值,值越小优先级越高  return 1;  }  
}

这个示例中,我们创建了一个名为CustomGlobalFilter的类,它实现了GlobalFilter和Ordered接口。在filter()方法中,我们可以执行一些在请求处理之前需要执行的操作。getOrder()方法返回该过滤器的优先级值,这里我们返回了1,表示该过滤器将优先执行。

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

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

相关文章

深入了解Docker镜像操作

Docker是一种流行的容器化平台&#xff0c;它允许开发者将应用程序及其依赖项打包成容器&#xff0c;以便在不同环境中轻松部署和运行。在Docker中&#xff0c;镜像是构建容器的基础&#xff0c;有些家人们可能在服务器上对docker镜像的操作命令不是很熟悉&#xff0c;本文将深…

【LeetCode-中等题】200. 岛屿数量

文章目录 题目方法一&#xff1a;深度优先搜索 dfs方法二&#xff1a;广度优先搜索 bfs方法三&#xff1a;&#xff08;重点掌握&#xff09;并查集 题目 方法一&#xff1a;深度优先搜索 dfs 思路&#xff1a;让一个扫描指针扫描每一个格子&#xff0c;然后每扫到一个为1的格…

Spring Boot日志基础使用 设置日志级别

然后 我们来说日志 日志在实际开发中还是非常重要的 即可记录项目状态和一些特殊情况发生 因为 我们这里不是将项目 所以 讲的也不会特别深 基本还是将Spring Boot的日志设置或控制这一类的东西 相对业务的领域我们就不涉及了 日志 log 初期最明显的作用在于 开发中 你可以用…

element+vue table表格全部数据和已选数据联动

1.组件TableChoose <template><div class"tableChooseBox"><div class"tableRow"><div class"tableCard"><div class"tableHeadTip">全部{{ labelTitle }}</div><slot name"body" …

OpenCV(十三):图像中绘制直线、圆形、椭圆形、矩形、多边形和文字

目录 1.绘制直线line() 2.绘制圆形circle() 3.绘制椭圆形ellipse() 4.绘制矩形rectangle() 5.绘制多边形 fillPoly() 6.绘制文字putText() 7.例子 1.绘制直线line() CV_EXPORTS_W void line(InputOutputArray img,Point pt1, Point pt2,const Scalar& color,int t…

无涯教程-Android Studio函数

第1步-系统要求 您将很高兴知道您可以在以下两种操作系统之一上开始Android应用程序的开发- MicrosoftWindows10/8/7/Vista/2003(32或64位)MacOSX10.8.5或更高版本,最高10.9(小牛) GNOME或KDE桌面 第二点是,开发Android应用程序所需的所有工具都是开源的,可以从Web上下载。以…

vue的第2篇 第一个vue程序

一 环境的搭建 1.1常见前端开发ide 1.2 安装vs.code 1.下载地址&#xff1a;Visual Studio Code - Code Editing. Redefined 2.进行安装 1.2.1 vscode的中文插件安装 1.在搜索框输入“chinese” 2.安装完成重启&#xff0c;如下变成中文 1.2.2 修改工作区的颜色 选中[浅色]…

编译KArchive在windows10下

使用QT6和VS2019编译KArchive的简要步骤&#xff1a; 安装 Qt &#xff0c;我是用源码自己编译的 "F:\qtbuild"安装CMakefile并配置环境变量安装Git下载ECM源码 https://github.com/KDE/extra-cmake-modules.git-------------------------------------------------…

SpringBoot Mybatis 多数据源 MySQL+Oracle

一、背景 在SpringBoot Mybatis 项目中&#xff0c;需要连接 多个数据源&#xff0c;连接多个数据库&#xff0c;需要连接一个MySQL数据库和一个Oracle数据库 二、依赖 pom.xml <dependencies><dependency><groupId>org.springframework.boot</groupId&…

上半年净利润同比改善22.18%,赛力斯的韧性从何而来?

2023年上半年&#xff0c;伴随特斯拉一声全球大降价&#xff0c;新能源汽车行业价格混战拉开帷幕&#xff0c;车企业绩纷纷承压。“卷”风盛行之下&#xff0c;谁抗住了压力&#xff1f; 8月30日&#xff0c;赛力斯发布了中期业绩报告。根据财报&#xff0c;2023年上半年&…

kotlin实现猜数游戏

游戏规则 1.程序随机生成一个1到100的数字&#xff0c;作为MagicNumber 2.用户根据提示输入数据&#xff0c;只有三次机会输入数据 代码 代码很简单&#xff0c;使用了let内置函数 fun main() {//生成随机数可以使用java的方法//val magicNumber Random().nextInt(11)val ma…

Tensorflow调用训练好的yolov5模型进行推理

文章目录 1、安装TensorFlow-GPU版本1.2、验证是否安装正常 2、将训练好的pt文件转换成onnx文件2.2、什么是Onnx模型和Tensorflow模型2.1、将onnx文件转换成pb文件 1、安装TensorFlow-GPU版本 1、创建虚拟环境python3.8 conda create -n TF2.4 python3.82、进入虚拟环境 conda…