业务开发时,接口不能对外暴露怎么办?我有 3 种实现方案!

在业务开发的时候,经常会遇到某一个接口不能对外暴露,只能内网服务间调用的实际需求。面对这样的情况,我们该如何实现呢?

今天,我们就来理一理这个问题,从几个可行的方案中,挑选一个来实现。

推荐一个开源免费的 Spring Boot 实战项目:

https://github.com/javastacks/spring-boot-best-practice

1. 内外网接口微服务隔离

将对外暴露的接口和对内暴露的接口分别放到两个微服务上,一个服务里所有的接口均对外暴露,另一个服务的接口只能内网服务间调用。

该方案需要额外编写一个只对内部暴露接口的微服务,将所有只能对内暴露的业务接口聚合到这个微服务里,通过这个聚合的微服务,分别去各个业务侧获取资源。

该方案,新增一个微服务做请求转发,增加了系统的复杂性,增大了调用耗时以及后期的维护成本。

2. 网关 + redis 实现白名单机制

在 redis 里维护一套接口白名单列表,外部请求到达网关时,从 redis 获取接口白名单,在白名单内的接口放行,反之拒绝掉。

该方案的好处是,对业务代码零侵入,只需要维护好白名单列表即可;

不足之处在于,白名单的维护是一个持续性投入的工作,在很多公司,业务开发无法直接触及到 redis,只能提工单申请,增加了开发成本;另外,每次请求进来,都需要判断白名单,增加了系统响应耗时,考虑到正常情况下外部进来的请求大部分都是在白名单内的,只有极少数恶意请求才会被白名单机制所拦截,所以该方案的性价比很低。

3. 方案三 网关 + AOP

相比于方案二对接口进行白名单判断而言,方案三是对请求来源进行判断,并将该判断下沉到业务侧。避免了网关侧的逻辑判断,从而提升系统响应速度。

我们知道,外部进来的请求一定会经过网关再被分发到具体的业务侧,内部服务间的调用是不用走外部网关的(走 k8s 的 service)。

根据这个特点,我们可以对所有经过网关的请求的header里添加一个字段,业务侧接口收到请求后,判断header里是否有该字段,如果有,则说明该请求来自外部,没有,则属于内部服务的调用,再根据该接口是否属于内部接口来决定是否放行该请求。

该方案将内外网访问权限的处理分布到各个业务侧进行,消除了由网关来处理的系统性瓶颈;同时,开发者可以在业务侧直接确定接口的内外网访问权限,提升开发效率的同时,增加了代码的可读性。

当然该方案会对业务代码有一定的侵入性,不过可以通过注解的形式,最大限度的降低这种侵入性。

图片

具体实操

下面就方案三,进行具体的代码演示。另外,如果你近期准备面试跳槽,建议在Java面试库小程序在线刷题,涵盖 2000+ 道 Java 面试题,几乎覆盖了所有主流技术面试题。

首先在网关侧,需要对进来的请求header添加外网标识符: from=public

@Component public class AuthFilter implements GlobalFilter, Ordered {     @Override     public Mono < Void > filter ( ServerWebExchange exchange, GatewayFilterChain chain ) {          return chain.filter(          exchange.mutate().request(          exchange.getRequest().mutate().header("id", "").header("from", "public").build())          .build()          );     }       @Override     public int getOrder () {         return 0;     }  } 

接着,编写内外网访问权限判断的AOP和注解

@Aspect @Component @Slf4j public class OnlyIntranetAccessAspect {  @Pointcut ( "@within(org.openmmlab.platform.common.annotation.OnlyIntranetAccess)" )  public void onlyIntranetAccessOnClass () {}  @Pointcut ( "@annotation(org.openmmlab.platform.common.annotation.OnlyIntranetAccess)" )  public void onlyIntranetAccessOnMethed () {  }    @Before ( value = "onlyIntranetAccessOnMethed() || onlyIntranetAccessOnClass()" )  public void before () {      HttpServletRequest hsr = (( ServletRequestAttributes ) RequestContextHolder.getRequestAttributes()) .getRequest ();      String from = hsr.getHeader ( "from" );      if ( !StringUtils.isEmpty( from ) && "public".equals ( from )) {         log.error ( "This api is only allowed invoked by intranet source" );         throw new MMException ( ReturnEnum.C_NETWORK_INTERNET_ACCESS_NOT_ALLOWED_ERROR);             }      }  }   @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface OnlyIntranetAccess { } 

最后,在只能内网访问的接口上加上@OnlyIntranetAccess注解即可

@GetMapping ( "/role/add" ) @OnlyIntranetAccess public String onlyIntranetAccess() {     return "该接口只允许内部服务调用"; } 

你学会了吗?

版权声明:本文为CSDN博主「肥肥技术宅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/m0_71777195/article/details/127243452

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用提到,服务网关对外暴露统一规范的接口,包括各个子系统的交互接口对外开放接口开发加密接口接口文档等服务。这意味着shiro也可以通过服务网关对外暴露接口。 然而,引用指出shiro主要是用于应用的安全认证和授权,它并没有专门的对外暴露接口的功能。shiro在JavaSE环境和JavaEE环境下都可以使用,但它并不是一个专门用于提供对外接口的框架。 所以,总结来说,虽然shiro可以在JavaEE环境中使用,但它并没有直接对外暴露接口的功能,这个功能需要通过其他方式实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [单点登录源码](https://download.csdn.net/download/gelunbu321/10197348)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [shiro 提供对外接口 实现一致性权限](https://blog.csdn.net/weixin_38168728/article/details/101475034)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [安全权限框架 —— Shiro(一)](https://blog.csdn.net/baidu_39560928/article/details/119929154)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值