微服务之网关安全基于Zuul并实现网关限流

2024-09-07 21:38

本文主要是介绍微服务之网关安全基于Zuul并实现网关限流,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

微服务网关安全

微服务架构下的问题

处理安全和业务逻辑耦合,增加了复杂性和变更成本

随着业务节点增加,认证服务器压力增大

多个微服务同时暴露,增加了外部访问的复杂性

通过网关处理流程

1、请求令牌。2、转发请求。3、返回令牌。4、转发令牌各客户端应用。5、携带令牌发送请求。6、校验令牌。7、返回校验结果信息。8、访问微服务。

实例

引入依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- https://mvnrepository.com/artifact/com.marcosbarbero.cloud/spring-cloud-zuul-ratelimit --><dependency><groupId>com.marcosbarbero.cloud</groupId><artifactId>spring-cloud-zuul-ratelimit</artifactId><version>2.3.0.RELEASE</version></dependency>
</dependencies>
增加配置文件application.yml
zuul:routes:token:url: http://localhost:8085order:url: http://localhost:9080#敏感头,有三个敏感头,cookie,set-cookie,Authorizationsensitive-headers:
增加验证token过滤器
/*** 验证token*/
@Component
@Slf4j
public class OAuthFilter extends ZuulFilter {@Autowiredprivate RestTemplate restTemplate;/*** 提供四种过滤类型,pre-请求前,post-请求之后,error-出错之后,route-控制路由* @return*/public String filterType() {return "pre";}/*** 过滤器执行顺序* @return*/public int filterOrder() {return 1;}/*** 过滤器是否起作用,true,启用过滤器* @return*/public boolean shouldFilter() {return true;}/*** 要写的业务逻辑* @return* @throws ZuulException*/public Object run() throws ZuulException {log.info("oauth start");RequestContext requestContext=RequestContext.getCurrentContext();HttpServletRequest request = requestContext.getRequest();//请求开头是不是以token开头的,发往认证服务器的请求不用验证if(StringUtils.startsWith(request.getRequestURI(),"/token")){return null;}String requestHeader=request.getHeader("Authorization");if(StringUtils.isBlank(requestHeader)){return null;}if(!StringUtils.startsWithIgnoreCase(requestHeader,"bearer ")){return null;}try{TokenInfo tokenInfo=getTokenInfo(requestHeader);request.setAttribute("tokenInfo",tokenInfo);}catch(Exception e){log.info("get token info fail:",e);}return null;}private TokenInfo getTokenInfo(String requestHeader) {String token=StringUtils.substringAfter(requestHeader,"bearer ");String oauthServiceUrl="http://localhost:8085/oauth/check_token";HttpHeaders httpHeaders=new HttpHeaders();httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);httpHeaders.setBasicAuth("gateway","123456");//只能用这个map,用hashmap什么的,报错MultiValueMap<String,String> params=new LinkedMultiValueMap<String, String>();params.put("token", Collections.singletonList(token));HttpEntity<MultiValueMap<String,String>> entity=new HttpEntity<MultiValueMap<String, String>>(params,httpHeaders);ResponseEntity<TokenInfo> response=restTemplate.exchange(oauthServiceUrl, HttpMethod.POST,entity,TokenInfo.class);log.info("token info:{}",response.getBody().toString());return response.getBody();}
}

创建自定义token响应,通过check_token接口拿到的token信息

@Data
public class TokenInfo {/*** token 是不是可用的*/private boolean active;/*** token是发往哪个客户端应用*/private String client_id;/*** 这个令牌的具有的权限*/private String[] scope;/*** 这个令牌发给哪个用户*/private String user_name;/*** 这个令牌哪些客户端ID可以访问*/private String[] aud;/*** 这个令牌的过期时间*/private Date exp;/*** 这个令牌所对应的用户的访问权限*/private String[] authorities;}

增加授权过滤器,在验证token过滤器之后执行,故filterOrder设置比验证token过滤器要大

/*** 授权过滤器*/
@Component
@Slf4j
public class AuthorizationFilter extends ZuulFilter {public String filterType() {return "pre";}public int filterOrder() {return 3;}public boolean shouldFilter() {return true;}public Object run() throws ZuulException {log.info("authorization start");RequestContext requestContext=RequestContext.getCurrentContext();HttpServletRequest request = requestContext.getRequest();/*** 权限判断,是否需要认证*/if(isNeedAuth(request)){TokenInfo tokenInfo = (TokenInfo) request.getAttribute("tokenInfo");if(tokenInfo!=null&&tokenInfo.isActive()){if(!hasPermission(tokenInfo,request)){log.info("audit log update fail 403");handleError(403,requestContext);}requestContext.addZuulRequestHeader("username",tokenInfo.getUser_name());}else{if(!StringUtils.startsWith(request.getRequestURI(),"/token")){log.info("audit log update fail 401");handleError(401,requestContext);return null;}}}else{}return null;}/*** 模拟获取权限请求,50%的概率报403* @param tokenInfo* @param request* @return*/private boolean hasPermission(TokenInfo tokenInfo, HttpServletRequest request) {
//        return RandomUtils.nextInt()%2==0;return true;}private void handleError(int i, RequestContext requestContext) {requestContext.getResponse().setContentType("application/json");requestContext.setResponseStatusCode(i);requestContext.setResponseBody("{\"message\":\"auth fail\"}");requestContext.setSendZuulResponse(false);}private boolean isNeedAuth(HttpServletRequest request) {return true;}
}
zuul限流配置

pom文件增加

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.marcosbarbero.cloud/spring-cloud-zuul-ratelimit -->
<dependency><groupId>com.marcosbarbero.cloud</groupId><artifactId>spring-cloud-zuul-ratelimit</artifactId><version>2.3.0.RELEASE</version>
</dependency>

yml配置文件增加限流配置

zuul:routes:token:url: http://localhost:8085order:url: http://localhost:9080#敏感头,有三个敏感头,cookie,set-cookie,Authorizationsensitive-headers:ratelimit:enabled: true #限流是否起作用repository: jpa #存储位置default-policy-list: #默认策略- limit: 2quota: 1refresh-interval: 3type:- url- httpmethodpolicy-list: #针对于上面配置具体的服务限流规则token:- limit: 2quota: 1refresh-interval: 3type:- url- httpmethod
测试

在这里插入图片描述

注:3秒之内连续发送请求,报429错误,超过3秒,返回200

这篇关于微服务之网关安全基于Zuul并实现网关限流的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

在Linux中改变echo输出颜色的实现方法

《在Linux中改变echo输出颜色的实现方法》在Linux系统的命令行环境下,为了使输出信息更加清晰、突出,便于用户快速识别和区分不同类型的信息,常常需要改变echo命令的输出颜色,所以本文给大家介... 目python录在linux中改变echo输出颜色的方法技术背景实现步骤使用ANSI转义码使用tpu

关于DNS域名解析服务

《关于DNS域名解析服务》:本文主要介绍关于DNS域名解析服务,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录DNS系统的作用及类型DNS使用的协议及端口号DNS系统的分布式数据结构DNS的分布式互联网解析库域名体系结构两种查询方式DNS服务器类型统计构建DNS域

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

golang版本升级如何实现

《golang版本升级如何实现》:本文主要介绍golang版本升级如何实现问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录golanwww.chinasem.cng版本升级linux上golang版本升级删除golang旧版本安装golang最新版本总结gola

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具