springcloudalibaba微服务实战三十四-隐私接口禁止外部访问(代码片段)

飘渺Jam 飘渺Jam     2022-12-16     775

关键词:

大家好,我是飘渺!

在这个系列文章中曾经介绍过在SpringCloud体系下如何防止前端请求绕过网关直接到达后端微服务,今天我们要反其道而行之,介绍在SpringCloud体系中如何防止内部隐私接口被网关调用。

看到这里可能有的同学会有点晕,怎么还有这种业务场景呢,别急,咱们先回顾一下我们的业务场景。

友情提示,这是系列文章,欢迎持续关注!此文在流量变少时会转入收费专栏,且看且珍惜!

业务场景

客户端通过网关调用OrderService服务获取数据,OrderService通过Feign调用AccountService服务,而当AccountService提供对应的Feign接口后,客户端是可以通过网关直接调用AccountService接口的。

现在假设AccountService提供的接口包含了部分隐私数据,只允许内部调用协助OrderService进行业务逻辑处理,不允许客户端直接获取,此时咱们需要怎么做?

业务实战

我们先通过代码将原始的流程实现出来,即通过网关调用OrderServiceOrderController,然后在OrderController中通过Feign调用AccountServiceAccountController,为了便于阅读,文章中删除了部分无用代码。

模拟实现

  1. 入口 OrderController
public class OrderController 
    private final OrderService orderService;
    private final AccountClient accountClient;


    @GetMapping("/order/orderNo")
    public ResultData<OrderDTO> getById(@PathVariable("orderNo") String orderNo)
        OrderDTO orderDTO = orderService.selectByNo(orderNo);
        ResultData<String> secretValue = accountClient.getSecretValue();
        log.info(secretValue);
        return ResultData.success(orderDTO);
    

OrderController中通过AccountClient调用AccountService

ResultData<String> secretValue = accountClient.getSecretValue();
  1. Feign接口
public interface AccountApi 
		...
    @GetMapping("/account/getSecretValue")
    ResultData<String> getSecretValue();
		...

  1. AccountController实现
@RestController
@Log4j2
@Api(tags = "account接口")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AccountController implements AccountApi 

    /**
     * 隐私接口,禁止通过网关访问
     */
    @Override
    @GetMapping("/account/getSecretValue")
    public ResultData<String> getSecretValue() 
        return ResultData.success("隐私接口,禁止通过网关访问");
    
    

正如我们前面所说,一旦提供了Feign接口,在默认情况下我们可以直接通过网关访问getSecretValue()方法,那怎么确保这个方法不让外部调用呢?

解决方案

网上现在大部分的解决办法是基于黑名单机制,即将这些接口放入“黑名单”中存储起来,在网关启动时读取黑名单配置,然后校验是否在黑名单中。

这种办法确实也可以,但是总感觉不够灵活,而且实现也比较繁琐,这里就不展开了。

我们今天介绍的是利用访问路径来实现,非常简单轻便。

实现原理

我们需要借助接口路径规范来实现,即给接口指定访问路径时采用这样的格式 : /访问控制/接口

访问控制可以有以下几个规则(参考JAVA包规范),可根据业务需要进行扩展。

pb - public 所有请求均可访问

pt - protected 需要进行token认证通过后方可访问

pv - private 无法通过网关访问,只能微服务内部调用

df - default 网关请求token认证,并且请求参数和返回结果进行加解密

...

有了这套接口规范以后,我们就可以灵活控制接口访问权限,然后在网关对接口路径进行校验,如果命中对应的访问控制规则就进行对应的逻辑处理。

代码实战

既然知道了实现原理,那写代码就很简单了。

  1. 修改接口访问路径,遵循接口路径规范
public interface AccountApi 
    @GetMapping("/pv/account/getSecretValue")
    ResultData<String> getSecretValue();

修改feign的访问路径。

@RestController
@Log4j2
@Api(tags = "account接口")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AccountController implements AccountApi 

    /**
     * 隐私接口,禁止通过网关访问
     */
    @Override
    @GetMapping("/pv/account/getSecretValue")
    public ResultData<String> getSecretValue() 
        return ResultData.success("隐私接口,禁止通过网关访问");
    
    

修改接口实现类的访问路径,这里需要与Feign的路径保持一致。

  1. 网关自定义拦截器进行接口校验
@Component
@Order(0)
@Slf4j
public class GatewayRequestFilter implements GlobalFilter 

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) 
        //获取请求路径
        String rawPath = exchange.getRequest().getURI().getRawPath();

        if(isPv(rawPath))
            throw new HttpServerErrorException(HttpStatus.FORBIDDEN,"can't access private API");
        
        return chain.filter(newExchange);
    

    /**
     * 判断是否内部私有方法
     * @param requestURI 请求路径
     * @return boolean
     */
    private boolean isPv(String requestURI) 
        return isAccess(requestURI,"/pv");
    

    /**
     * 网关访问控制校验
     */
    private boolean isAccess(String requestURI, String access) 
        //后端标准请求路径为 /访问控制/请求路径
        int index = requestURI.indexOf(access);
        return index >= 0 && StringUtils.countOccurrencesOf(requestURI.substring(0,index),"/") < 1;
    


通过上面简单两步我们就能实现本文提出的问题了,接下来我们测试一下。

测试

  1. 直接访问后端服务,提示无法访问

  1. 通过OrderService访问后端服务正常访问

小结

让内部隐私接口不被外部访问,我相信做微服务开发的同学基本都会遇到。本文中提供的解决方案代码量很少而且接口路径规范可以根据自己的业务规则进行修改扩展,推荐大家使用。其实代码不是关键,关键在于要让团队共同遵守这个接口规范,思想比实现更重要

我是飘渺Jam,一名写代码的架构师,做架构的程序员,期待您的转发与关注,咱们下期见!

springcloudalibaba微服务实战三十四-隐私接口禁止外部访问(代码片段)

大家好,我是飘渺!在这个系列文章中曾经介绍过在SpringCloud体系下如何防止前端请求绕过网关直接到达后端微服务,今天我们要反其道而行之,介绍在SpringCloud体系中如何防止内部隐私接口被网关调用。看到这里... 查看详情

springcloudalibaba微服务实战三十七-oauth2自定义登录接口

...给大家送书了~)有不少人私下问我,为什么SpringCloudalibaba实战系列不更新了,主要是因为大部分核心功能都已经讲完了,剩下的基本是属于业务功能开发了,需要根据实际业务扩展。今天更新文章的原因... 查看详情

springcloudalibaba微服务实战三十七-oauth2自定义登录接口(代码片段)

大家好,我是飘渺。有不少人私下问我,为什么SpringCloudalibaba实战系列不更新了,主要是因为大部分核心功能都已经讲完了,剩下的基本是属于业务功能开发了,需要根据实际业务扩展。今天更新文章的原因是粉丝提了个问题:... 查看详情

springcloudalibaba微服务实战三十七-oauth2自定义登录接口(代码片段)

大家好,我是飘渺。有不少人私下问我,为什么SpringCloudalibaba实战系列不更新了,主要是因为大部分核心功能都已经讲完了,剩下的基本是属于业务功能开发了,需要根据实际业务扩展。今天更新文章的原因是粉丝提了个问题:... 查看详情

汇总

个人感觉这是全网比较齐全,写的比较好的SpringCloudalibaba系列教程了,推荐给大家!SpringCloudAlibaba微服务实战一-基础环境准备SpringCloudAlibaba微服务实战二-服务注册SpringCloudAlibaba微服务实战三-服务调用SpringCloudAlibaba微... 查看详情

汇总

个人感觉这是全网比较齐全,写的比较好的SpringCloudalibaba系列教程了,推荐给大家!SpringCloudAlibaba微服务实战一-基础环境准备SpringCloudAlibaba微服务实战二-服务注册SpringCloudAlibaba微服务实战三-服务调用SpringCloudAlibaba微... 查看详情

springcloudalibaba微服务实战教程系列

一、应用系列     Docker安装MySql完整教程、实操 使用到的mysql数据库的安装方案。     Docker安装AlibabaNacos教程  docker安装单实例或集群的Nacos的注册中心方便快速开始。    实现Nacos服... 查看详情

springcloudalibaba微服务实战二-服务注册

导读:在之前一篇文章中我们准备好了基于SpringCloudAlibaba的基础组件,本期主要内容是将所有的服务注册进Nacos,并让account-service和product-service能对外提供基础的增删改查能力。基础框架搭建在你的IDEA中建立一个多模块的项目(... 查看详情

springcloudalibaba微服务实战一-基础环境准备(代码片段)

SpringcloudAibaba现在这么火,我一直想写个基于SpringcloudAlibaba一步一步构建微服务架构的系列博客,终于下定决心从今天开始本系列文章的第一篇-基础环境准备。该系列文章内容主要基于三个微服务:用户服务AccountService,订单服... 查看详情

springcloudalibaba微服务实战二十一-jwt增强

今天内容主要是解决一位粉丝提的问题:如何在jwt中添加用户的额外信息并在资源服务器中获取这些数据。涉及的知识点有以下三个:如何在返回的jwt中添加自定义数据如何在jwt中添加用户的额外数据,比如用户id、手机号码如... 查看详情

springcloudalibaba微服务实战十四-springcloudgateway集成oauth2.0(代码片段)

导读:上篇文章我们已经抽取出了单独的认证服务,本章主要内容是让SpringCloudGateway集成Oauth2。概念部分在网关集成Oauth2.0后,我们的流程架构如上。主要逻辑如下:1、客户端应用通过api网关请求认证服务器获取a... 查看详情

springcloudalibaba微服务实战二十二-整合dubbo

概述在SpringCloud构建的微服务系统中,大多数的开发者使用都是官方提供的Feign组件来进行内部服务通信,这种声明式的HTTP客户端使用起来非常的简洁、方便、优雅,但是有一点,在使用Feign消费服务的时候,相比较Dubbo这种RPC框... 查看详情

微服务实战:选择微服务部署策略

 微服务实战(一):微服务架构的优势与不足微服务实战(二):使用APIGateway微服务实战(三):深入微服务架构的进程间通信微服务实战(四):服务发现的可行方案以及实践案例微服务实践(五):微服务的事件驱动... 查看详情

chrisrichardson微服务实战系列

微服务实战(一):微服务架构的优势与不足微服务实战(二):使用APIGateway微服务实战(三):深入微服务架构的进程间通信微服务实战(四):服务发现的可行方案以及实践案例微服务实践(五):微服务的事件驱动数据... 查看详情

3.20go微服务实战(微服务实战)---日志和监控

第20章 日志和监控20.1 日志实践20.2 指标 20.2.1 指标数据类型 20.2.2 命名约定 20.2.3 存储和查询 20.2.4 Grafana20.3 日志记录 20.3.1 具有关联ID的分布式跟踪 20.3.2 ElasticSearch、Logstash和Kibana 20.3.3 Kibana 20.4 异常    查看详情

3.20go微服务实战(微服务实战)---日志和监控

第20章 日志和监控20.1 日志实践20.2 指标 20.2.1 指标数据类型 20.2.2 命名约定 20.2.3 存储和查询 20.2.4 Grafana20.3 日志记录 20.3.1 具有关联ID的分布式跟踪 20.3.2 ElasticSearch、Logstash和Kibana 20.3.3 Kibana 20.4 异常    查看详情

3.21go微服务实战(微服务实战)---持续交付

第21章 持续交付21.1 持续交付简介 21.1.1 手动部署 21.1.2 持续交付的好处 21.1.3 持续交付面面观 21.1.4 持续交付的过程21.2 容器编排的选项和基础架构21.3 Terraform 21.3.1 提供者 21.3.2 Terraform配置入口点 21.3.3 VPC模块 21.3.... 查看详情

3.21go微服务实战(微服务实战)---持续交付

第21章 持续交付21.1 持续交付简介 21.1.1 手动部署 21.1.2 持续交付的好处 21.1.3 持续交付面面观 21.1.4 持续交付的过程21.2 容器编排的选项和基础架构21.3 Terraform 21.3.1 提供者 21.3.2 Terraform配置入口点 21.3.3 VPC模块 21.3.... 查看详情