Implementing Internal‑Only APIs with Microservice Isolation, Redis Whitelist, and Gateway + AOP
This article explores three practical solutions for exposing APIs only to internal services—microservice isolation, a Redis‑based whitelist via the gateway, and a gateway‑plus‑AOP approach—detailing their trade‑offs and providing complete Java code examples for the chosen method.
Introduction
When developing business services, you may encounter the requirement that certain interfaces must not be exposed externally and should only be callable between internal services. This article examines three feasible solutions and selects one for implementation.
Feasible Solutions
Three approaches are considered:
Microservice isolation of internal and external interfaces
Redis‑based whitelist mechanism combined with a gateway
Gateway plus AOP to determine access rights on the business side
1. Microservice Isolation
Separate external‑exposed APIs and internal‑only APIs into two distinct microservices. The internal service aggregates all APIs that should only be called within the intranet.
This adds a new microservice for request forwarding, increasing system complexity, latency, and maintenance cost.
2. Gateway + Redis Whitelist
Maintain a whitelist of allowed interfaces in Redis. When a request reaches the gateway, the whitelist is consulted; requests on the list are allowed, others are rejected.
Advantages: zero intrusion into business code; only the whitelist needs maintenance.
Drawbacks: whitelist upkeep requires continuous effort, often needing tickets from developers; each request incurs a whitelist check, adding latency, and the cost‑benefit ratio is low because most traffic is legitimate.
3. Gateway + AOP
Instead of checking the whitelist at the gateway, this approach pushes the source‑checking logic to the business side via AOP, reducing gateway load and improving response speed.
All external requests pass through the gateway; internal service‑to‑service calls bypass it (e.g., via k8s Service).
The gateway adds a custom header (e.g., from=public) to external requests. Business services inspect this header; if present, the request is external and may be blocked for internal‑only APIs.
This distributes access‑control logic across services, eliminates a gateway bottleneck, and improves code readability, though it introduces some code intrusion that can be mitigated with annotations.
Practical Implementation (Solution 3)
First, add an identifier to the request header on the gateway side: from=public Java example of a gateway filter that injects the 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, create an AOP aspect and annotation to enforce 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 internal‑only endpoint with @OnlyIntranetAccess:
@GetMapping("/role/add")
@OnlyIntranetAccess
public String onlyIntranetAccess() {
return "该接口只允许内部服务调用";
}That concludes the implementation.
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.
