2015-08-27 15 views
6

Do sprawdzenia bezpieczeństwa potrzebuję dostępu do zdalnego adresu IP użytkownika w mojej usłudze zasobów. Serwis ten zasób jest prosta niedawno app Wiosna Boot, który rejestruje się z moim serwerze Eureka:Uzyskiwanie dostępu do zdalnego adresu IP na serwerze zasobów proxy za pośrednictwem Zuul i Apache

@SpringBootApplication 
@EnableEurekaClient 
public class ServletInitializer extends SpringBootServletInitializer { 
    public static void main(final String[] args) { 
     SpringApplication.run(ServletInitializer.class, args); 
    } 
} 

Wszystkie usługi zarejestrowanych z mojego serwera Eureka dynamicznie kierowane przez moją Zuul serwera proxy routing w oparciu o Angel.SR3 starter-zuul i starter-eureka :

@SpringBootApplication 
@EnableZuulProxy 
@EnableEurekaClient 
public class RoutingProxyServer { 
    public static void main(final String[] args) { 
     SpringApplication.run(RoutingProxyServer.class, args); 
    } 
} 

serwer proxy trasowania Zuul konfiguruje również złącze AJP do następnego etapu:

@Configuration 
@ConditionalOnProperty("ajp.port") 
public class TomcatAjpConfig extends TomcatWebSocketContainerCustomizer { 
    @Value("${ajp.port}") 
    private int port; 

    @Override 
    public void doCustomize(final TomcatEmbeddedServletContainerFactory tomcat) { 
     super.doCustomize(tomcat); 

     // Listen for AJP requests 
     Connector ajp = new Connector("AJP/1.3"); 
     ajp.setPort(port); 
     tomcat.addAdditionalTomcatConnectors(ajp); 
    } 
} 

Wszystkie wnioski do dynamicznego routingu Zuul pełnomocnika są przekierowywane siebie poprzez Apache dostarczyć HTTPS na standardowym 443 port:

# Preserve Host when proxying so jar apps return working URLs in JSON responses 
RequestHeader   set X-Forwarded-Proto "https" 
ProxyPreserveHost On 
# Redirect remaining traffic to routing proxy server 
ProxyPass  /  ajp://192.168.x.x:8009/ 
# Also update Location, Content-Location and URI headers on HTTP redirect responses 
ProxyPassReverse /  ajp://192.168.x.x:8009/ 

Mając to wszystko na miejscu usługa zasób jest dostępny, ale niestety remoteAddress że dostanę od Spring Security jest adresem serwera proxy Zuul/Apache, a nie adresem IP klienta zdalnego.

W przeszłości używał org.springframework.security.authentication.AuthenticationDetailsSource że preferowaną wartość X-Forwarded-For nagłówka nad normalnym remoteAddress aby uzyskać prawidłowy adres IP, ale nie może pracować się, jak przekazać właściwej zdalny adres IP do mojego usługi zasobów podczas przechodzenia przez dwóch serwerów proxy (Apache + Zuul).

Czy ktoś może mi pomóc uzyskać dostęp do prawidłowego zdalnego adresu IP za tymi dwoma serwerami proxy lub zaproponować alternatywne podejście, aby to zadziałało?

Odpowiedz

4

Okazuje się nagłówek X-Przekazano-For został zaczerpnięty z oryginalnego żądania karmienia w Zuul zapełnić HttpServletRequest#getRemoteAddr(). Musiałoby to następnie zostać przekazane do serwerów proxy usług przez RequestContext#getZuulRequestHeaders().put("X-Forwarded-For", remoteAddr). Następujące ZuulFilter to osiąga, nawet jeśli nie dodaje jeszcze własnej wartości do filtra X-Forwarded-For.

@Component 
@Slf4j 
public class XForwardedForFilter extends ZuulFilter { 
private static final String X_FORWARDED_FOR = "X-Forwarded-For"; 

@Override 
public Object run() { 
    RequestContext ctx = RequestContext.getCurrentContext(); 

    // Rely on HttpServletRequest to retrieve the correct remote address from upstream X-Forwarded-For header 
    HttpServletRequest request = ctx.getRequest(); 
    String remoteAddr = request.getRemoteAddr(); 

    // Pass remote address downstream by setting X-Forwarded for header again on Zuul request 
    log.debug("Settings X-Forwarded-For to: {}", remoteAddr); 
    ctx.getZuulRequestHeaders().put(X_FORWARDED_FOR, remoteAddr); 

    return null; 
} 

@Override 
public boolean shouldFilter() { 
    return true; 
} 

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

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

Jeden może chcesz wyczyścić wartość nagłówka w Apache przed proxy do Zuul aby zapobiec przyjmując byle wartość podaną przez użytkownika: RequestHeader unset X-Forwarded-For

+0

Naprawiono w https://github.com/spring-cloud/spring-cloud-netflix/pull/952 – Tim

1

Zwykle można użyć servletRequest.getRemoteAddr(), aby uzyskać adres IP klienta, który uzyskuje dostęp do aplikacji WWW Java.

String ipAddress = request.getRemoteAddr(); 

Ale, jeśli użytkownik znajduje się za serwerem proxy lub dostęp do serwera WWW za pomocą równoważenia obciążenia (na przykład w cloud hostingu), powyższy kod będzie uzyskać adres IP serwera, serwer proxy lub równoważenia obciążenia , a nie oryginalny adres IP klienta.

Aby rozwiązać ten problem, należy uzyskać adres IP nagłówka żądania żądania "X-Forwarded-For (XFF)".

String ipAddress = request.getHeader("X-FORWARDED-FOR"); 
    if (ipAddress == null) { 
     ipAddress = request.getRemoteAddr(); 
    } 
+1

to co zrobiłem przed dodałem Zuul, ale to podejście nie jest już Prace. Nagłówki nie są przekazywane i/lub otrzymuję adres serwera proxy. Patrz od drugiego do ostatniego akapitu. – Tim

Powiązane problemy