Updates for boot 2 and spring security 5

This commit is contained in:
Spencer Gibb
2017-10-30 23:45:21 -04:00
parent 16a8cbbe7b
commit cbad81f737
12 changed files with 40 additions and 37 deletions

View File

@@ -63,7 +63,7 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security-reactive</artifactId>
<artifactId>spring-boot-starter-security</artifactId>
<optional>true</optional>
</dependency>
<dependency>

View File

@@ -40,6 +40,7 @@ class GatewayRedisAutoConfiguration {
}
@Bean
//TODO: replace with ReactiveStringRedisTemplate in future
public ReactiveRedisTemplate<String, String> stringReactiveRedisTemplate(
ReactiveRedisConnectionFactory reactiveRedisConnectionFactory,
ResourceLoader resourceLoader) {
@@ -57,7 +58,7 @@ class GatewayRedisAutoConfiguration {
@Bean
public RedisRateLimiter redisRateLimiter(ReactiveRedisTemplate<String, String> redisTemplate,
@Qualifier("redisRequestRateLimiterScript") RedisScript<String> redisScript) {
@Qualifier("redisRequestRateLimiterScript") RedisScript<List<Long>> redisScript) {
return new RedisRateLimiter(redisTemplate, redisScript);
}
}

View File

@@ -24,10 +24,10 @@ public class RedisRateLimiter implements RateLimiter {
private Log log = LogFactory.getLog(getClass());
private final ReactiveRedisTemplate<String, String> redisTemplate;
private final RedisScript script;
private final RedisScript<List<Long>> script;
public RedisRateLimiter(ReactiveRedisTemplate<String, String> redisTemplate,
RedisScript script) {
RedisScript<List<Long>> script) {
this.redisTemplate = redisTemplate;
this.script = script;
}
@@ -57,13 +57,13 @@ public class RedisRateLimiter implements RateLimiter {
List<String> args = Arrays.asList(replenishRate + "", burstCapacity + "",
Instant.now().getEpochSecond() + "", "1");
// allowed, tokens_left = redis.eval(SCRIPT, keys, args)
Flux<Long> flux = this.redisTemplate.execute(this.script, keys, args)
Flux<List<Long>> 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<Long>(), (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);

View File

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

View File

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

View File

@@ -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<PathMatchInfo> constructor = ReflectionUtils.accessibleConstructor(PathMatchInfo.class, Map.class, Map.class);

View File

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

View File

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

View File

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

View File

@@ -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<String, Object> headers(ServerWebExchange exchange) {
HashMap<String, Object> 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<String, Object> 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<String, Object> get(ServerWebExchange exchange) {
HashMap<String, Object> 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<Map<String, Object>> postFormData(@RequestBody Mono<MultiValueMap<String, Part>> 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<Map<String, Object>> postUrlEncoded(ServerWebExchange exchange) throws IOException {
return post(exchange, null);
}
@RequestMapping("/post")
@RequestMapping(path = "/post", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<Map<String, Object>> post(ServerWebExchange exchange,
@RequestBody(required = false) String body) throws IOException {
HashMap<String, Object> ret = new HashMap<>();

View File

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

View File

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