0

I have Spring Boot based micro-services environment setup with this configuration -

  1. nginx as the load balancer on centos 7. (configured to use x-forwarded-for)
  2. Spring boot powered API Gateway based on netflix zuul proxy server. Tomcat is embedded container.
  3. Products micro-service based on Spring Cloud. Tomcat as the embedded container.

Spring Boot version : 1.5.6

When end user is making call to Product Microservice, it goes through Nginx -> Api gateway -> Products Service.

Now the problem comes when i want to get the Remote Client IP Address in products Microservice. I always get 127.0.0.1 as the ip address. Here is the code in Products microservice that fetches client IP

private String getClientIP() {       
    String xfHeader = request.getRemoteAddr();
    if (StringUtils.isBlank(xfHeader) || xfHeader.equals("127.0.0.1")) {
        return request.getHeader("X-Forwarded-For");
    }
    return xfHeader.split(",")[0];
}

API Gateway application.properties are configured to use server.use-forward-headers: true

P.S. When i tries switching from tomcat to undertow in my api-gateway, then i start getting the real client ip address in products microservice. So problem lies somewhere in my Tomcat Configuration in API Gateway.

Munish Chandel
  • 3,572
  • 3
  • 24
  • 35

1 Answers1

0

you can create zuul filter and change location like this

zuul:
  ignoreSecurityHeaders: false
  routes:
    app:
      path: /app/**
      sensitiveHeaders: 
      url: http://localhost:8082/app/
server:
    compression:
        enabled: true
    port: 80

and filter

package smartHomeWebsite;

import java.util.Optional;

import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.UrlPathHelper;

import com.netflix.util.Pair;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

@Component
public class LocationHeaderRewritingFilter extends ZuulFilter {

    private final UrlPathHelper urlPathHelper = new UrlPathHelper();
    private final RouteLocator routeLocator;

    public LocationHeaderRewritingFilter(RouteLocator routeLocator) {
        this.routeLocator = routeLocator;
    }

    @Override
    public String filterType() {
        return "post";
    }

    @Override
    public int filterOrder() {
        return 100;
    }

    public boolean shouldFilter() {
        return extractLocationHeader(RequestContext.getCurrentContext()).isPresent();
    }

    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        Route route = routeLocator.getMatchingRoute(urlPathHelper.getPathWithinApplication(ctx.getRequest()));
        if (route != null) {
            Pair<String, String> lh = extractLocationHeader(ctx).get();
            lh.setSecond(lh.second().replace(route.getLocation(),
                    ServletUriComponentsBuilder.fromCurrentContextPath().path(route.getPrefix()).build().toUriString()));
        }
        return null;
    }


    private Optional<Pair<String, String>> extractLocationHeader(RequestContext ctx) {

        return ctx.getZuulResponseHeaders()
                .stream()
                .filter(p -> "Location".equals(p.first()))
                .findFirst();
    }
}
ali akbar azizkhani
  • 2,213
  • 5
  • 31
  • 48