Backend Development 7 min read

How to Secure Internal APIs with Microservice Isolation, Redis Whitelists, and AOP

This article explores three practical approaches—microservice isolation, Redis‑based whitelist, and gateway‑AOP integration—to restrict internal‑only APIs, compares their trade‑offs, and provides step‑by‑step SpringBoot code examples for implementing the AOP solution.

macrozheng
macrozheng
macrozheng
How to Secure Internal APIs with Microservice Isolation, Redis Whitelists, and AOP

Introduction

When developing business services, you may encounter interfaces that must not be exposed externally and should only be callable between internal services. This article examines how to achieve that requirement.

Possible Solutions

Three feasible schemes are considered: microservice isolation for internal/external APIs, a Redis‑backed whitelist enforced by the gateway, and a gateway‑plus‑AOP approach that delegates access control to the business side.

Solution 1: Microservice Isolation for Internal and External APIs

Separate the publicly exposed interfaces and the internal‑only interfaces into two distinct microservices. One service exposes all APIs externally, while the other aggregates only internal APIs for intra‑network calls.

This adds an extra microservice for request forwarding, increasing system complexity, latency, and maintenance cost.

Solution 2: Gateway + Redis Whitelist

Maintain a whitelist of allowed interfaces in Redis. When a request reaches the gateway, the whitelist is consulted; requests matching the list are allowed, others are rejected.

The advantage is zero intrusion into business code—only the whitelist needs upkeep. However, maintaining the whitelist requires ongoing effort, and each request incurs a lookup cost, making the cost‑benefit ratio low for most scenarios.

Solution 3: Gateway + AOP

Instead of checking a whitelist at the gateway, this scheme tags requests with a header indicating their origin and lets the business side decide access based on that header, reducing gateway load and improving response speed.

By adding a custom header (e.g.,

from=public

) at the gateway, services can inspect the header; if it is absent, the call is considered internal. An AOP aspect can enforce this rule, optionally using an annotation to minimize code intrusion.

Practical Implementation

First, modify the gateway to add the

from=public

header to incoming requests.

<code>@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;
    }
}
</code>

Next, create an AOP aspect and a custom annotation to enforce internal‑only access.

<code>@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 {}
</code>

Finally, annotate any internal‑only endpoint with

@OnlyIntranetAccess

.

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

This completes the AOP‑based solution for restricting internal API access.

JavaMicroservicesAOPRedisSpringBootgatewayAPI security
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.