diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRoutePredicateFactory.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRoutePredicateFactory.java index c94bb965..22dcc96b 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRoutePredicateFactory.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRoutePredicateFactory.java @@ -17,6 +17,16 @@ package org.springframework.cloud.gateway.handler.predicate; +import io.netty.handler.ipfilter.IpFilterRuleType; +import io.netty.handler.ipfilter.IpSubnetFilterRule; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.cloud.gateway.support.ipresolver.RemoteAddressResolver; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.server.ServerWebExchange; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Arrays; @@ -24,20 +34,8 @@ import java.util.Collections; import java.util.List; import java.util.function.Predicate; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.cloud.gateway.support.ipresolver.RemoteAddressResolver; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.server.ServerWebExchange; - import static org.springframework.cloud.gateway.support.ShortcutConfigurable.ShortcutType.GATHER_LIST; -import io.netty.handler.ipfilter.IpFilterRuleType; -import io.netty.handler.ipfilter.IpSubnetFilterRule; - /** * @author Spencer Gibb */ @@ -74,7 +72,7 @@ public class RemoteAddrRoutePredicateFactory extends AbstractRoutePredicateFacto return exchange -> { InetSocketAddress remoteAddress = config.remoteAddressResolver.resolve(exchange); - if (remoteAddress != null) { + if (remoteAddress != null && remoteAddress.getAddress() != null) { String hostAddress = remoteAddress.getAddress().getHostAddress(); String host = exchange.getRequest().getURI().getHost(); diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolver.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolver.java index 6589d903..c146245e 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolver.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolver.java @@ -93,7 +93,7 @@ public class XForwardedRemoteAddressResolver implements RemoteAddressResolver { Collections.reverse(xForwardedValues); if (xForwardedValues.size() != 0) { int index = Math.min(xForwardedValues.size(), maxTrustedIndex) - 1; - return InetSocketAddress.createUnresolved(xForwardedValues.get(index), 0); + return new InetSocketAddress(xForwardedValues.get(index), 0); } return defaultRemoteIpResolver.resolve(exchange); } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRoutePredicateFactoryTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRoutePredicateFactoryTests.java index c1fbbc58..a941219e 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRoutePredicateFactoryTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRoutePredicateFactoryTests.java @@ -5,10 +5,15 @@ import static org.springframework.cloud.gateway.test.TestUtils.assertStatus; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; +import org.springframework.cloud.gateway.support.ipresolver.XForwardedRemoteAddressResolver; import org.springframework.cloud.gateway.test.BaseWebClientTests; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; import org.springframework.test.annotation.DirtiesContext; @@ -44,10 +49,31 @@ public class RemoteAddrRoutePredicateFactoryTests extends BaseWebClientTests { .expectComplete().verify(DURATION); } + @Test + public void remoteAddrWorksWithXForwardedRemoteAddress() { + Mono result = webClient.get().uri("/xforwardfor") + .header("X-Forwarded-For", "12.34.56.78").exchange(); + + StepVerifier.create(result) + .consumeNextWith(response -> assertStatus(response, HttpStatus.OK)) + .expectComplete().verify(DURATION); + } + @EnableAutoConfiguration @SpringBootConfiguration @Import(DefaultTestConfig.class) public static class TestConfig { + @Value("${test.uri}") + String uri; + + @Bean + public RouteLocator testRouteLocator(RouteLocatorBuilder builder) { + return builder.routes().route("x_forwarded_for_test", r -> r + .path("/xforwardfor").and() + .remoteAddr(XForwardedRemoteAddressResolver.maxTrustedIndex(1), + "12.34.56.78") + .filters(f -> f.setStatus(200)).uri(uri)).build(); + } } }