From cbad81f737d2da5547a7a20f7e1cbee7a67f5797 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Mon, 30 Oct 2017 23:45:21 -0400 Subject: [PATCH] Updates for boot 2 and spring security 5 --- spring-cloud-gateway-core/pom.xml | 2 +- .../config/GatewayRedisAutoConfiguration.java | 3 ++- .../gateway/filter/ratelimit/RedisRateLimiter.java | 12 ++++++------ ...equestRateLimiterGatewayFilterFactoryTests.java | 4 ++-- .../RewritePathGatewayFilterFactoryTests.java | 4 ++-- .../factory/SetPathGatewayFilterFactoryTests.java | 4 ++-- .../PrincipalNameKeyResolverIntegrationTests.java | 14 +++++++------- .../BetweenRoutePredicateFactoryTests.java | 4 ++-- .../handler/predicate/RoutePredicatesTest.java | 8 ++++---- .../cloud/gateway/test/BaseWebClientTests.java | 13 +++++++------ .../test/PermitAllSecurityConfiguration.java | 5 +++-- .../cloud/gateway/route/GatewayDslTests.kt | 4 ++-- 12 files changed, 40 insertions(+), 37 deletions(-) diff --git a/spring-cloud-gateway-core/pom.xml b/spring-cloud-gateway-core/pom.xml index 4625e185..321a9497 100644 --- a/spring-cloud-gateway-core/pom.xml +++ b/spring-cloud-gateway-core/pom.xml @@ -63,7 +63,7 @@ org.springframework.boot - spring-boot-starter-security-reactive + spring-boot-starter-security true diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayRedisAutoConfiguration.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayRedisAutoConfiguration.java index b67993fe..0474b4e9 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayRedisAutoConfiguration.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayRedisAutoConfiguration.java @@ -40,6 +40,7 @@ class GatewayRedisAutoConfiguration { } @Bean + //TODO: replace with ReactiveStringRedisTemplate in future public ReactiveRedisTemplate stringReactiveRedisTemplate( ReactiveRedisConnectionFactory reactiveRedisConnectionFactory, ResourceLoader resourceLoader) { @@ -57,7 +58,7 @@ class GatewayRedisAutoConfiguration { @Bean public RedisRateLimiter redisRateLimiter(ReactiveRedisTemplate redisTemplate, - @Qualifier("redisRequestRateLimiterScript") RedisScript redisScript) { + @Qualifier("redisRequestRateLimiterScript") RedisScript> redisScript) { return new RedisRateLimiter(redisTemplate, redisScript); } } diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/ratelimit/RedisRateLimiter.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/ratelimit/RedisRateLimiter.java index 6a689c1c..82534c83 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/ratelimit/RedisRateLimiter.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/ratelimit/RedisRateLimiter.java @@ -24,10 +24,10 @@ public class RedisRateLimiter implements RateLimiter { private Log log = LogFactory.getLog(getClass()); private final ReactiveRedisTemplate redisTemplate; - private final RedisScript script; + private final RedisScript> script; public RedisRateLimiter(ReactiveRedisTemplate redisTemplate, - RedisScript script) { + RedisScript> script) { this.redisTemplate = redisTemplate; this.script = script; } @@ -57,13 +57,13 @@ public class RedisRateLimiter implements RateLimiter { List args = Arrays.asList(replenishRate + "", burstCapacity + "", Instant.now().getEpochSecond() + "", "1"); // allowed, tokens_left = redis.eval(SCRIPT, keys, args) - Flux flux = this.redisTemplate.execute(this.script, keys, args) + Flux> flux = this.redisTemplate.execute(this.script, keys, args) .log("redisratelimiter", Level.FINER); - return flux.onErrorResume(throwable -> Flux.just(1L, -1L)) + return flux.onErrorResume(throwable -> Flux.just(Arrays.asList(1L, -1L))) .reduce(new ArrayList(), (longs, l) -> { - longs.add(l); + longs.addAll(l); return longs; - }).map(results -> { + }) .map(results -> { boolean allowed = results.get(0) == 1L; Long tokensLeft = results.get(1); diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestRateLimiterGatewayFilterFactoryTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestRateLimiterGatewayFilterFactoryTests.java index e0114d70..9e2d6493 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestRateLimiterGatewayFilterFactoryTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestRateLimiterGatewayFilterFactoryTests.java @@ -17,7 +17,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.http.server.reactive.MockServerWebExchange; +import org.springframework.mock.web.server.MockServerWebExchange; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; @@ -72,7 +72,7 @@ public class RequestRateLimiterGatewayFilterFactoryTests extends BaseWebClientTe MockServerHttpRequest request = MockServerHttpRequest.get("/").build(); - MockServerWebExchange exchange = new MockServerWebExchange(request); + MockServerWebExchange exchange = MockServerWebExchange.from(request); exchange.getResponse().setStatusCode(HttpStatus.OK); when(this.filterChain.filter(exchange)).thenReturn(Mono.empty()); diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RewritePathGatewayFilterFactoryTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RewritePathGatewayFilterFactoryTests.java index bf83f8c4..d5fc7cfc 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RewritePathGatewayFilterFactoryTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RewritePathGatewayFilterFactoryTests.java @@ -24,7 +24,7 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.http.server.reactive.MockServerWebExchange; +import org.springframework.mock.web.server.MockServerWebExchange; import org.springframework.web.server.ServerWebExchange; import static org.assertj.core.api.Assertions.assertThat; @@ -61,7 +61,7 @@ public class RewritePathGatewayFilterFactoryTests { .get("http://localhost"+ actualPath) .build(); - ServerWebExchange exchange = new MockServerWebExchange(request); + ServerWebExchange exchange = MockServerWebExchange.from(request); GatewayFilterChain filterChain = mock(GatewayFilterChain.class); diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SetPathGatewayFilterFactoryTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SetPathGatewayFilterFactoryTests.java index a1be5e88..a5aeea19 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SetPathGatewayFilterFactoryTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SetPathGatewayFilterFactoryTests.java @@ -28,7 +28,7 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.http.server.reactive.MockServerWebExchange; +import org.springframework.mock.web.server.MockServerWebExchange; import org.springframework.util.ReflectionUtils; import org.springframework.web.server.ServerWebExchange; import org.springframework.cloud.gateway.filter.GatewayFilterChain; @@ -69,7 +69,7 @@ public class SetPathGatewayFilterFactoryTests { .get("http://localhost"+ actualPath) .build(); - ServerWebExchange exchange = new MockServerWebExchange(request); + ServerWebExchange exchange = MockServerWebExchange.from(request); try { Constructor constructor = ReflectionUtils.accessibleConstructor(PathMatchInfo.class, Map.class, Map.class); diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/ratelimit/PrincipalNameKeyResolverIntegrationTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/ratelimit/PrincipalNameKeyResolverIntegrationTests.java index 976ed162..35f1ade2 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/ratelimit/PrincipalNameKeyResolverIntegrationTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/ratelimit/PrincipalNameKeyResolverIntegrationTests.java @@ -18,8 +18,8 @@ import org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewa import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.Routes; import org.springframework.context.annotation.Bean; -import org.springframework.security.config.web.server.HttpSecurity; -import org.springframework.security.core.userdetails.MapUserDetailsRepository; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.server.SecurityWebFilterChain; @@ -32,9 +32,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; +import static org.springframework.cloud.gateway.filter.factory.GatewayFilters.prefixPath; import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory.BURST_CAPACITY_KEY; import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory.REPLENISH_RATE_KEY; -import static org.springframework.cloud.gateway.filter.factory.GatewayFilters.prefixPath; import static org.springframework.cloud.gateway.handler.predicate.RoutePredicates.path; import static org.springframework.tuple.TupleBuilder.tuple; import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.basicAuthentication; @@ -112,7 +112,7 @@ public class PrincipalNameKeyResolverIntegrationTests { } @Bean - SecurityWebFilterChain springWebFilterChain(HttpSecurity http) throws Exception { + SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception { return http.httpBasic().and() .authorizeExchange() .pathMatchers("/myapi/**").authenticated() @@ -122,9 +122,9 @@ public class PrincipalNameKeyResolverIntegrationTests { } @Bean - public MapUserDetailsRepository userDetailsRepository() { - UserDetails user = User.withUsername("user").password("password").roles("USER").build(); - return new MapUserDetailsRepository(user); + public MapReactiveUserDetailsService reactiveUserDetailsService() { + UserDetails user = User.withUsername("user").password("{noop}password").roles("USER").build(); + return new MapReactiveUserDetailsService(user); } } } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BetweenRoutePredicateFactoryTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BetweenRoutePredicateFactoryTests.java index b85a4126..51bd2325 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BetweenRoutePredicateFactoryTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BetweenRoutePredicateFactoryTests.java @@ -22,7 +22,7 @@ import java.time.format.DateTimeFormatter; import org.junit.Test; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.http.server.reactive.MockServerWebExchange; +import org.springframework.mock.web.server.MockServerWebExchange; import org.springframework.web.server.ServerWebExchange; import static org.assertj.core.api.Assertions.assertThat; @@ -128,6 +128,6 @@ public class BetweenRoutePredicateFactoryTests { static ServerWebExchange getExchange() { MockServerHttpRequest request = MockServerHttpRequest.get("http://example.com").build(); - return new MockServerWebExchange(request); + return MockServerWebExchange.from(request); } } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/RoutePredicatesTest.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/RoutePredicatesTest.java index 672873eb..e89605d0 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/RoutePredicatesTest.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/RoutePredicatesTest.java @@ -20,7 +20,7 @@ package org.springframework.cloud.gateway.handler.predicate; import org.junit.Test; import org.springframework.http.HttpMethod; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.http.server.reactive.MockServerWebExchange; +import org.springframework.mock.web.server.MockServerWebExchange; import org.springframework.web.server.ServerWebExchange; import static org.assertj.core.api.Assertions.assertThat; @@ -59,17 +59,17 @@ public class RoutePredicatesTest { private ServerWebExchange mockHostExchange(String host) { MockServerHttpRequest mockRequest = MockServerHttpRequest.get("/") .header("Host", host).build(); - return new MockServerWebExchange(mockRequest); + return MockServerWebExchange.from(mockRequest); } private ServerWebExchange mockPathExchange(String path) { MockServerHttpRequest mockRequest = MockServerHttpRequest.get(path).build(); - return new MockServerWebExchange(mockRequest); + return MockServerWebExchange.from(mockRequest); } private ServerWebExchange mockMethodExchange(String method) { MockServerHttpRequest mockRequest = MockServerHttpRequest .method(HttpMethod.resolve(method), "/").build(); - return new MockServerWebExchange(mockRequest); + return MockServerWebExchange.from(mockRequest); } } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/BaseWebClientTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/BaseWebClientTests.java index 86d2c36c..325613fe 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/BaseWebClientTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/BaseWebClientTests.java @@ -46,6 +46,7 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.server.ServerWebExchange; @@ -100,7 +101,7 @@ public class BaseWebClientTests { return "httpbin compatible home"; } - @RequestMapping("/headers") + @RequestMapping(path = "/headers", method = {RequestMethod.GET, RequestMethod.POST}, produces = MediaType.APPLICATION_JSON_VALUE) public Map headers(ServerWebExchange exchange) { HashMap map = new HashMap<>(); addHeaders(exchange, map); @@ -116,14 +117,14 @@ public class BaseWebClientTests { map.put("headers", headers); } - @RequestMapping("/delay/{sec}") + @RequestMapping(path = "/delay/{sec}", produces = MediaType.APPLICATION_JSON_VALUE) public Map get(ServerWebExchange exchange, @PathVariable int sec) throws InterruptedException { int delay = Math.min(sec, 10); Thread.sleep(delay * 1000); return get(exchange); } - @RequestMapping("/get") + @RequestMapping(path = "/get", produces = MediaType.APPLICATION_JSON_VALUE) public Map get(ServerWebExchange exchange) { HashMap map = new HashMap<>(); addHeaders(exchange, map); @@ -136,7 +137,7 @@ public class BaseWebClientTests { return map; } - @RequestMapping(value = "/post", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @RequestMapping(value = "/post", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public Mono> postFormData(@RequestBody Mono> parts) { // StringDecoder decoder = StringDecoder.allMimeTypes(true); return parts.flux().flatMap(map -> Flux.fromIterable(map.values())) @@ -150,12 +151,12 @@ public class BaseWebClientTests { }).map(files -> Collections.singletonMap("files", files)); } - @RequestMapping(path = "/post", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + @RequestMapping(path = "/post", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public Mono> postUrlEncoded(ServerWebExchange exchange) throws IOException { return post(exchange, null); } - @RequestMapping("/post") + @RequestMapping(path = "/post", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) public Mono> post(ServerWebExchange exchange, @RequestBody(required = false) String body) throws IOException { HashMap ret = new HashMap<>(); diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/PermitAllSecurityConfiguration.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/PermitAllSecurityConfiguration.java index b5675f1d..ef260d59 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/PermitAllSecurityConfiguration.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/PermitAllSecurityConfiguration.java @@ -2,16 +2,17 @@ package org.springframework.cloud.gateway.test; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.web.server.HttpSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.web.server.SecurityWebFilterChain; @Configuration public class PermitAllSecurityConfiguration { @Bean - SecurityWebFilterChain springWebFilterChain(HttpSecurity http) throws Exception { + SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception { return http.authorizeExchange() .anyExchange().permitAll() .and() + .csrf().disable() .build(); } } diff --git a/spring-cloud-gateway-kotlin-extensions/src/test/kotlin/org/springframework/cloud/gateway/route/GatewayDslTests.kt b/spring-cloud-gateway-kotlin-extensions/src/test/kotlin/org/springframework/cloud/gateway/route/GatewayDslTests.kt index b0138af3..e2bc1da2 100644 --- a/spring-cloud-gateway-kotlin-extensions/src/test/kotlin/org/springframework/cloud/gateway/route/GatewayDslTests.kt +++ b/spring-cloud-gateway-kotlin-extensions/src/test/kotlin/org/springframework/cloud/gateway/route/GatewayDslTests.kt @@ -5,7 +5,7 @@ import org.springframework.cloud.gateway.filter.factory.GatewayFilters.addRespon import org.springframework.cloud.gateway.handler.predicate.RoutePredicates.host import org.springframework.cloud.gateway.handler.predicate.RoutePredicates.path import org.springframework.mock.http.server.reactive.MockServerHttpRequest -import org.springframework.mock.http.server.reactive.MockServerWebExchange +import org.springframework.mock.web.server.MockServerWebExchange import org.springframework.web.server.ServerWebExchange import reactor.test.StepVerifier import java.net.URI @@ -42,7 +42,7 @@ class GatewayDslTests { .expectComplete() .verify() - val sampleExchange: ServerWebExchange = MockServerWebExchange(MockServerHttpRequest.get("/image/webp") + val sampleExchange: ServerWebExchange = MockServerWebExchange.from(MockServerHttpRequest.get("/image/webp") .header("Host", "test.abc.org").build()) val filteredRoutes = routeLocator.routes.filter({ r -> r.predicate.test(sampleExchange) })