Implementing Internal‑Only APIs with Microservice Isolation, Gateway Whitelist, and AOP in Java
This article explains how to restrict certain APIs to internal network calls by comparing three approaches—microservice isolation, gateway + Redis whitelist, and gateway + AOP—and provides a complete Java implementation of the AOP solution with code examples.
When developing business services, you may encounter the need for interfaces that cannot be exposed externally and must be called only between internal services. This article examines three feasible solutions and selects one for detailed implementation.
1. Internal‑External Interface Microservice Isolation
Separate externally exposed interfaces and internally exposed interfaces into two microservices: one service whose APIs are all public, and another service whose APIs are only callable within the internal network.
This approach requires an additional microservice that aggregates all internal‑only business interfaces, acting as a request forwarder. While it isolates concerns, it adds system complexity, increases latency, and raises maintenance costs.
2. Gateway + Redis Whitelist Mechanism
Maintain a whitelist of allowed interfaces in Redis. When an external request reaches the gateway, the gateway checks Redis; if the interface is on the whitelist it is allowed, otherwise it is rejected.
Advantages: zero intrusion into business code, only whitelist maintenance is needed. Drawbacks: continuous effort to maintain the whitelist, often requiring ticket submissions; each request incurs a whitelist lookup, adding response time, and the cost‑benefit ratio is low because most traffic is legitimate.
3. Gateway + AOP Approach
Instead of checking the whitelist at the gateway, this method determines the request source and delegates the check to the business side, reducing gateway load and improving response speed.
External requests always pass through the gateway, while internal service‑to‑service calls bypass it (e.g., via Kubernetes Service). By adding a custom header (e.g., from=public) at the gateway, business services can inspect the header: if present, the request is external; if absent, it is internal.
The business side uses an AOP aspect and a custom annotation to enforce internal‑only access, allowing developers to mark APIs with @OnlyIntranetAccess. This distributes access control, eliminates gateway bottlenecks, and improves code readability, though it introduces some code intrusion that can be mitigated with annotations.
Specific Implementation
First, add the external identifier header in the gateway filter:
@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, create the AOP aspect and annotation for internal‑only access:
@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, annotate any API that should be internal‑only:
@GetMapping("/role/add")
@OnlyIntranetAccess
public String onlyIntranetAccess() {
return "该接口只允许内部服务调用";
}The article concludes with a reference to the original source and promotional links.
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.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
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.
