Securing Spring Cloud Gateway Requests with Token Filters and Feign Header Interceptor
This article demonstrates how to secure microservice communication by adding a request token in Spring Cloud Gateway, implementing a global filter to validate the token, and configuring a Feign interceptor to automatically attach the required header, ensuring all services route through the gateway.
In a microservice architecture, the gateway is a critical entry point where various filters can be added to validate request parameters, enforce rate limiting, and ensure security. Bypassing the gateway would allow direct access to internal services, so protecting the gateway is essential.
Idea
Add a request token to every request passing through the gateway.
In each downstream service, add a filter that validates the token.
First, create a global filter in the gateway service that injects a custom header (e.g., "from": "gateway") into every outgoing request.
package com.hpsyche.hpsychegatewayserver.filter;
import com.hpsyche.hpsychegatewayserver.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* @author Hpsyche
*/
public class TokenFilter implements GlobalFilter {
@Autowired
private RedisUtil redisUtil;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// token (user identity) validation
// ...
ServerHttpRequest req = exchange.getRequest().mutate()
.header("from", "gateway")
.build();
return chain.filter(exchange.mutate().request(req.mutate().build()).build());
}
}If higher security is required, the header value can be a UUID stored in Redis and verified by downstream services.
Next, add a global interceptor in the authentication service to check the from header. If the header is missing or incorrect, the service returns an error response.
package com.hpsyche.hpsycheauthserver.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
* @author Hpsyche
*/
@Slf4j
public class GlobalInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String secretKey = request.getHeader("from");
if (!StringUtils.isNotBlank(secretKey) || secretKey.equals("gateway")) {
response.setContentType("application/json; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("error");
return false;
}
return true;
}
}When a request bypasses the gateway and directly calls the auth service, the interceptor returns an error, confirming that the gateway is mandatory.
Problem
Feign remote calls failed because Feign does not go through the gateway, so the required from header is missing and the interceptor blocks the request.
Solution
Add a Feign request interceptor that automatically adds the from header, and configure the Feign client to use this interceptor.
package com.hpsyche.hpsycheauthclient.config;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
/**
* Feign interceptor to add the "from" header
*/
@Configuration
public class FeignConfiguration implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header("from", "gateway");
}
}Also, specify the interceptor in the Feign client definition:
package com.hpsyche.hpsycheauthclient.api;
import com.hpsyche.hpsychecommonscommon.vo.BaseResponse;
import com.hpsyche.hpsycheauthclient.config.FeignConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "hpsyche-auth-server", configuration = FeignConfiguration.class)
public interface AuthService {
@PostMapping("/auth/verifyUser")
BaseResponse verifyUser(@RequestParam("username") String username,
@RequestParam("password") String password);
}With this configuration, every Feign call automatically includes the required header, allowing the request to pass through the gateway and be accepted by the authentication service.
Conclusion
When building microservice systems, think carefully about security at the gateway level, add necessary request metadata, and ensure that all internal calls (including Feign) propagate this metadata. Leveraging Spring Cloud Gateway filters and Feign interceptors provides a clean, reusable solution.
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.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
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.
