Fix NPE in XForwardedRemoteAddressResolver

Adds an integration test that reproduces the bug 

Fixes gh-536
This commit is contained in:
Erko Risthein
2018-10-06 01:49:50 +03:00
committed by Spencer Gibb
parent 480ebcd149
commit 5f528ea326
3 changed files with 38 additions and 14 deletions

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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<ClientResponse> 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();
}
}
}