How to Prevent External Exposure of Internal APIs in Business Development
When a business service needs an API that should only be callable within the internal network, this article evaluates three approaches—microservice isolation, gateway‑Redis whitelist, and gateway‑AOP—and demonstrates a concrete AOP implementation to enforce intranet‑only access.
1. Feasible Solutions
1.1 Solution 1 – Microservice Isolation
Separate external‑exposed interfaces and internal‑only interfaces into two microservices: one service publishes all public APIs, while another aggregates only the intranet APIs. This requires building an extra microservice, increasing system complexity, request latency, and long‑term maintenance cost.
1.2 Solution 2 – Gateway + Redis Whitelist
Maintain a whitelist of allowed interfaces in Redis. When a request reaches the gateway, the gateway fetches the whitelist from Redis and allows the request only if the interface is listed. The advantage is zero intrusion to business code; only the whitelist needs upkeep. The drawbacks are continuous maintenance of the whitelist (often requiring ticket submission), added latency for every request, and a low cost‑performance ratio because most traffic is legitimate and the extra check rarely blocks anything.
1.3 Solution 3 – Gateway + AOP
Instead of checking a whitelist at the gateway, add a header (e.g., from=public) to all external requests. Business services read this header; if present, the request is considered external and the service decides whether to allow it based on the API’s intranet‑only designation. This moves permission logic to each service, eliminates the gateway bottleneck, and improves response speed. It does introduce some code intrusion, which can be mitigated with a custom annotation.
2. Concrete Implementation (Solution 3)
First, the gateway filter adds the identifying header:
@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;
}
}Next, an AOP aspect intercepts methods annotated with @OnlyIntranetAccess and validates the header:
@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 onlyIntranetAccessOnMethod() {}
@Before(value = "onlyIntranetAccessOnMethod() || 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 {}Finally, apply the annotation to an intranet‑only endpoint:
@GetMapping("/role/add")
@OnlyIntranetAccess
public String onlyIntranetAccess() {
return "该接口只允许内部服务调用";
}The article concludes with an illustration image (omitted here) and notes that the presented approach balances security with minimal impact on existing business code.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IoT Full-Stack Technology
Dedicated to sharing IoT cloud services, embedded systems, and mobile client technology, with no spam ads.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
