Implementing Internal‑Only APIs with Gateway and AOP in a Microservice System
This article explains how to restrict certain microservice interfaces to internal calls only by using two approaches—gateway with whitelist and gateway combined with AOP—detailing the implementation steps, code examples, and trade‑offs in a Spring Cloud environment.
When a service needs an interface that should not be exposed externally, developers can choose between two common solutions: a gateway with a whitelist or a gateway combined with AOP. The whitelist approach stores allowed endpoints in a cache and lets the gateway filter requests, but it requires ongoing maintenance and adds latency.
The gateway + AOP method moves the source‑checking logic to the business side, improving response time. By adding a custom header (e.g., from=Y) to internal requests, the gateway can strip the header for security, and an AOP aspect validates the header before the controller method executes.
Implementation Steps
1. Define an annotation to mark internal‑only endpoints:
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Inner {
/**
* Whether AOP should handle this annotation
*/
boolean value() default true;
}2. Gateway filter that removes the from header and records request start time:
/**
* {@link com.code.ape.codeape.gateway.filter.CodeapeRequestGlobalFilter#filter}
* @author 公众号:码猿技术专栏
* @url: www.java-family.cn
*/
public class CodeapeRequestGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1. Clean the "from" header
ServerHttpRequest request = exchange.getRequest().mutate().headers(httpHeaders -> {
httpHeaders.remove(SecurityConstants.FROM);
// Set request start time
httpHeaders.put(CommonConstants.REQUEST_START_TIME,
Collections.singletonList(String.valueOf(System.currentTimeMillis())));
}).build();
// ... further processing ...
}
}3. Feign client that automatically adds the header for internal calls:
@FeignClient(contextId = "remoteDeviceService", value = ServiceNameConstants.DEVICE_SERVICE)
public interface RemoteDeviceService {
/**
* Query device by SN
*/
@GetMapping(value = "/device/sn/{sn}", headers = "from=Y")
R<DeviceInfoVO> getBySn(@PathVariable("sn") String sn);
}4. AOP aspect that checks the from header and throws AccessDeniedException if the request is not internal:
// com.code.ape.codeape.common.security.component.CodeapeSecurityInnerAspect
@Slf4j
@Aspect
@RequiredArgsConstructor
public class CodeapeSecurityInnerAspect implements Ordered {
private final HttpServletRequest request;
@SneakyThrows
@Around("@within(inner) || @annotation(inner)")
public Object around(ProceedingJoinPoint point, Inner inner) {
// Retrieve the "from" header
String header = request.getHeader("from");
// Verify header value
if (inner.value() && !"Y".equals(header)) {
log.warn("Access to method {} is denied", point.getSignature().getName());
throw new AccessDeniedException("Access is denied");
}
return point.proceed();
}
// ... other methods ...
}When the header check fails, the aspect throws an exception that is caught globally and results in a 403 response.
Summary
The article presented two ways to keep certain microservice APIs internal: a gateway + whitelist and a gateway + AOP solution. The latter reduces gateway load by delegating the check to the service layer, uses a custom @Inner annotation, and integrates seamlessly with Feign clients via the from=Y header.
Choosing the appropriate method depends on project requirements, maintenance overhead, and performance considerations.
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.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
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.
