Backend Development 7 min read

How to Secure Internal‑Only APIs with SpringBoot, Gateway, Redis, and AOP

This article explores three practical approaches—microservice isolation, Redis‑based whitelist, and gateway‑AOP header checks—to restrict certain APIs to internal network calls, and provides step‑by‑step SpringBoot code examples for implementing the preferred gateway‑AOP solution.

macrozheng
macrozheng
macrozheng
How to Secure Internal‑Only APIs with SpringBoot, Gateway, Redis, and AOP

When developing business services, you may encounter APIs that should not be exposed externally and must be callable only between internal services.

Feasible Solutions

Three approaches are considered: isolating internal and external APIs with separate microservices, using Redis with a gateway to enforce a whitelist, and adding an AOP check in the business side after the gateway.

Solution 1 – Microservice Isolation

Place public and internal APIs in two different microservices; the internal‑only service aggregates all internal endpoints and is called only by other internal services. This adds a new service, increasing system complexity and latency.

Solution 2 – Gateway + Redis Whitelist

Maintain a whitelist of allowed interfaces in Redis. The gateway checks each incoming request against the list and forwards only those in the whitelist. This requires no changes to business code but incurs ongoing maintenance of the whitelist and adds a lookup overhead for every request.

Solution 3 – Gateway + AOP Header Check

The preferred method adds a custom header (e.g.,

from=public

) at the gateway. Downstream services read the header; if it indicates a public request, the service rejects the call for methods annotated as internal‑only. This moves the access control to the business side, reduces gateway load, and improves response time, at the cost of a small amount of code intrusion.

Implementation Details (Solution 3)

1. Add a filter on the gateway to set the header:

<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>

2. Define an annotation and an AOP aspect 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>

3. Annotate internal‑only endpoints:

<code>@GetMapping("/role/add")
@OnlyIntranetAccess
public String onlyIntranetAccess() {
    return "该接口只允许内部服务调用";
}
</code>
MicroservicesAOPRedisSpringBootgatewayAPI 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.