diff --git a/spring-cloud-gateway-server-mvc/pom.xml b/spring-cloud-gateway-server-mvc/pom.xml index 01c47d60..c44dada5 100644 --- a/spring-cloud-gateway-server-mvc/pom.xml +++ b/spring-cloud-gateway-server-mvc/pom.xml @@ -104,6 +104,16 @@ spring-boot-testcontainers test + + org.springframework.boot + spring-boot-starter-security + test + + + org.springframework.security + spring-security-test + test + org.springframework.cloud spring-cloud-starter-stream-rabbit diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java index 4efa9b8c..51f4145e 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java @@ -40,6 +40,7 @@ import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; import jakarta.servlet.http.HttpServletRequest; import org.assertj.core.api.Assertions; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -61,10 +62,13 @@ import org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPred import org.springframework.cloud.gateway.server.mvc.test.HttpbinTestcontainers; import org.springframework.cloud.gateway.server.mvc.test.HttpbinUriResolver; import org.springframework.cloud.gateway.server.mvc.test.LocalServerPortUriResolver; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.TestLoadBalancerConfig; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Lazy; import org.springframework.core.Ordered; import org.springframework.core.io.ClassPathResource; import org.springframework.http.HttpEntity; @@ -83,10 +87,12 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import org.springframework.web.servlet.function.HandlerFunction; import org.springframework.web.servlet.function.RouterFunction; import org.springframework.web.servlet.function.ServerRequest; import org.springframework.web.servlet.function.ServerResponse; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.cloud.gateway.server.mvc.filter.AfterFilterFunctions.DedupeStrategy.RETAIN_FIRST; @@ -142,12 +148,15 @@ import static org.springframework.web.servlet.function.RequestPredicates.POST; import static org.springframework.web.servlet.function.RequestPredicates.path; @SuppressWarnings("unchecked") -@SpringBootTest(properties = { "spring.http.client.factory=jdk", "spring.cloud.gateway.function.enabled=false" }, - webEnvironment = WebEnvironment.RANDOM_PORT) +@SpringBootTest(properties = { "spring.http.client.factory=jdk", "spring.cloud.gateway.function.enabled=false", + "logging.level.org.springframework.security=TRACE" }, webEnvironment = WebEnvironment.RANDOM_PORT) @ContextConfiguration(initializers = HttpbinTestcontainers.class) @ExtendWith(OutputCaptureExtension.class) public class ServerMvcIntegrationTests { + public static final MediaType FORM_URL_ENCODED_CONTENT_TYPE = new MediaType(APPLICATION_FORM_URLENCODED, + StandardCharsets.UTF_8); + static { // if set type to autodetect above System.setProperty("sun.net.http.allowRestrictedHeaders", "true"); @@ -162,6 +171,12 @@ public class ServerMvcIntegrationTests { @Autowired TestRestClient restClient; + private static boolean isPNG(byte[] bytes) { + byte[] pngSignature = { (byte) 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; + byte[] header = Arrays.copyOf(bytes, pngSignature.length); + return Arrays.equals(pngSignature, header); + } + @Test public void nonGatewayRouterFunctionWorks() { restClient.get().uri("/hello").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("Hello"); @@ -317,7 +332,7 @@ public class ServerMvcIntegrationTests { .isEqualTo(HttpStatus.TOO_MANY_REQUESTS) .expectHeader() .valueEquals("x-status", "201"); // .expectBody(String.class).isEqualTo("Failed - // with 201"); + // with 201"); } @Test @@ -588,9 +603,6 @@ public class ServerMvcIntegrationTests { .isOk(); } - public static final MediaType FORM_URL_ENCODED_CONTENT_TYPE = new MediaType(APPLICATION_FORM_URLENCODED, - StandardCharsets.UTF_8); - @Test void formUrlencodedWorks() { LinkedMultiValueMap formData = new LinkedMultiValueMap<>(); @@ -671,12 +683,6 @@ public class ServerMvcIntegrationTests { } } - private static boolean isPNG(byte[] bytes) { - byte[] pngSignature = { (byte) 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; - byte[] header = Arrays.copyOf(bytes, pngSignature.length); - return Arrays.equals(pngSignature, header); - } - @Test public void removeRequestHeaderWorks() { restClient.get() @@ -1027,6 +1033,8 @@ public class ServerMvcIntegrationTests { @EnableAutoConfiguration @LoadBalancerClient(name = "httpbin", configuration = TestLoadBalancerConfig.Httpbin.class) protected static class TestConfiguration { + @Import(PermitAllSecurityConfiguration.class) + protected static class TestConfiguration extends WebMvcConfigurationSupport { @Bean StaticPortController staticPortController() { @@ -1043,6 +1051,23 @@ public class ServerMvcIntegrationTests { return new EventController(); } + // TODO This is needed to work around https://github.com/spring-cloud/spring-cloud-gateway/issues/3816 + // which results from Spring Security being on the classpath. Once we can address this issue we should + // remove this bean and no longer extend WebMvcConfigurationSupport in this configuration class + @Bean + @Lazy + @Override + public @NotNull HandlerMappingIntrospector mvcHandlerMappingIntrospector() { + return new HandlerMappingIntrospector() { + @Override + public @NotNull Filter createCacheFilter() { + return (request, response, chain) -> { + chain.doFilter(request, response); + }; + } + }; + } + @Bean public AsyncProxyManager caffeineProxyManager() { Caffeine builder = (Caffeine) Caffeine.newBuilder().maximumSize(100); @@ -1667,6 +1692,12 @@ public class ServerMvcIntegrationTests { private static class MyFilter implements Filter, Ordered { + static boolean isFormPost(HttpServletRequest request) { + String contentType = request.getContentType(); + return (contentType != null && contentType.contains(MediaType.APPLICATION_FORM_URLENCODED_VALUE) + && HttpMethod.POST.matches(request.getMethod())); + } + @Override public int getOrder() { return FormFilter.FORM_FILTER_ORDER - 1; @@ -1689,12 +1720,6 @@ public class ServerMvcIntegrationTests { } } - static boolean isFormPost(HttpServletRequest request) { - String contentType = request.getContentType(); - return (contentType != null && contentType.contains(MediaType.APPLICATION_FORM_URLENCODED_VALUE) - && HttpMethod.POST.matches(request.getMethod())); - } - } protected record Hello(String message) { diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/VanillaRouterFunctionTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/VanillaRouterFunctionTests.java index 81d1128c..4d22c81e 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/VanillaRouterFunctionTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/VanillaRouterFunctionTests.java @@ -29,10 +29,12 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.cloud.gateway.server.mvc.test.HttpbinTestcontainers; import org.springframework.cloud.gateway.server.mvc.test.HttpbinUriResolver; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.TestLoadBalancerConfig; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.test.context.ContextConfiguration; import org.springframework.web.servlet.function.RouterFunction; import org.springframework.web.servlet.function.RouterFunctions; @@ -43,8 +45,7 @@ import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFuncti import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.host; @SuppressWarnings("unchecked") -@SpringBootTest(properties = { "spring.http.client.factory=jdk" }, - webEnvironment = WebEnvironment.RANDOM_PORT) +@SpringBootTest(properties = { "spring.http.client.factory=jdk" }, webEnvironment = WebEnvironment.RANDOM_PORT) @ContextConfiguration(initializers = HttpbinTestcontainers.class) public class VanillaRouterFunctionTests { @@ -73,6 +74,7 @@ public class VanillaRouterFunctionTests { @SpringBootConfiguration @EnableAutoConfiguration @LoadBalancerClient(name = "httpbin", configuration = TestLoadBalancerConfig.Httpbin.class) + @Import(PermitAllSecurityConfiguration.class) protected static class TestConfiguration { @Bean diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/FunctionHandlerConfigTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/FunctionHandlerConfigTests.java index 779bc5bd..a1c4e671 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/FunctionHandlerConfigTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/FunctionHandlerConfigTests.java @@ -26,8 +26,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; @@ -78,6 +80,7 @@ public class FunctionHandlerConfigTests { @SpringBootConfiguration @EnableAutoConfiguration + @Import(PermitAllSecurityConfiguration.class) protected static class TestConfiguration { @Bean diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/GatewayMvcPropertiesBeanDefinitionRegistrarTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/GatewayMvcPropertiesBeanDefinitionRegistrarTests.java index f0d34697..fef64b4b 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/GatewayMvcPropertiesBeanDefinitionRegistrarTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/GatewayMvcPropertiesBeanDefinitionRegistrarTests.java @@ -34,11 +34,13 @@ import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.cloud.context.refresh.ContextRefresher; import org.springframework.cloud.gateway.server.mvc.common.MvcUtils; import org.springframework.cloud.gateway.server.mvc.test.HttpbinTestcontainers; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.TestLoadBalancerConfig; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Import; import org.springframework.core.io.Resource; import org.springframework.http.HttpMethod; import org.springframework.test.context.ActiveProfiles; @@ -230,6 +232,7 @@ public class GatewayMvcPropertiesBeanDefinitionRegistrarTests { @SpringBootConfiguration @EnableAutoConfiguration @LoadBalancerClient(name = "httpbin", configuration = TestLoadBalancerConfig.Httpbin.class) + @Import(PermitAllSecurityConfiguration.class) static class Config { } diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/StreamHandlerConfigTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/StreamHandlerConfigTests.java index 5227cc70..2c49d22e 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/StreamHandlerConfigTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/StreamHandlerConfigTests.java @@ -31,8 +31,10 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; @@ -88,6 +90,7 @@ public class StreamHandlerConfigTests { @SpringBootConfiguration @EnableAutoConfiguration + @Import(PermitAllSecurityConfiguration.class) protected static class TestConfiguration { @Bean diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/TokenRelayConfigTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/TokenRelayConfigTests.java new file mode 100644 index 00000000..86e8c222 --- /dev/null +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/TokenRelayConfigTests.java @@ -0,0 +1,97 @@ +/* + * Copyright 2013-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.gateway.server.mvc.config; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.gateway.server.mvc.test.HttpbinTestcontainers; +import org.springframework.cloud.gateway.server.mvc.test.TestAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.http.HttpHeaders; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * @author Ryan Baxter + */ +@SpringBootTest(webEnvironment = RANDOM_PORT) +@ContextConfiguration(initializers = HttpbinTestcontainers.class) +@ActiveProfiles("tokenrelay") +public class TokenRelayConfigTests { + + @Autowired + private WebApplicationContext context; + + private MockMvc mvc; + + @BeforeEach + public void setup() { + mvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build(); + } + + @Test + @WithMockUser + public void testTokenRelay() throws Exception { + mvc.perform(get("/bearer")) + .andExpect(status().isOk()) + .andExpect(content().json("{\"authenticated\": true, \"token\": \"test\"}")); + } + + @EnableAutoConfiguration + @SpringBootConfiguration + @Import(TestAutoConfiguration.class) + public static class TestConfig { + + @Bean + public OAuth2AuthorizedClientManager authorizedClientManager() { + OAuth2AuthorizedClientManager manager = mock(OAuth2AuthorizedClientManager.class); + OAuth2AuthorizedClient client = mock(OAuth2AuthorizedClient.class); + OAuth2AccessToken accessToken = mock(OAuth2AccessToken.class); + when(accessToken.getTokenValue()).thenReturn("test"); + when(client.getAccessToken()).thenReturn(accessToken); + // The client registration id is set in the token relay filter and must match + when(manager.authorize(argThat( + oAuth2AuthorizeRequest -> "token".equals(oAuth2AuthorizeRequest.getClientRegistrationId())))) + .thenReturn(client); + return manager; + } + + } + +} diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/AfterFilterFunctionsTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/AfterFilterFunctionsTests.java index cbb6e0a6..d498544f 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/AfterFilterFunctionsTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/AfterFilterFunctionsTests.java @@ -27,10 +27,12 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.gateway.server.mvc.test.HttpbinTestcontainers; import org.springframework.cloud.gateway.server.mvc.test.HttpbinUriResolver; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.TestLoadBalancerConfig; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -117,6 +119,7 @@ class AfterFilterFunctionsTests { @SpringBootConfiguration @EnableAutoConfiguration @LoadBalancerClient(name = "httpbin", configuration = TestLoadBalancerConfig.Httpbin.class) + @Import(PermitAllSecurityConfiguration.class) protected static class TestConfiguration { @Bean diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/BodyFilterFunctionsTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/BodyFilterFunctionsTests.java index 9479d7fc..180772ac 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/BodyFilterFunctionsTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/BodyFilterFunctionsTests.java @@ -26,10 +26,12 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.gateway.server.mvc.test.HttpbinTestcontainers; import org.springframework.cloud.gateway.server.mvc.test.HttpbinUriResolver; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.TestLoadBalancerConfig; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.ContextConfiguration; import org.springframework.web.servlet.function.RouterFunction; @@ -84,6 +86,7 @@ public class BodyFilterFunctionsTests { @SpringBootConfiguration @EnableAutoConfiguration @LoadBalancerClient(name = "httpbin", configuration = TestLoadBalancerConfig.Httpbin.class) + @Import(PermitAllSecurityConfiguration.class) protected static class TestConfiguration { @Bean diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/RetryFilterFunctionTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/RetryFilterFunctionTests.java index d93dfc57..80f29f29 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/RetryFilterFunctionTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/RetryFilterFunctionTests.java @@ -32,10 +32,12 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.cloud.gateway.server.mvc.test.HttpbinTestcontainers; import org.springframework.cloud.gateway.server.mvc.test.LocalServerPortUriResolver; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.TestLoadBalancerConfig; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.core.log.LogMessage; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -96,6 +98,7 @@ public class RetryFilterFunctionTests { @SpringBootConfiguration @EnableAutoConfiguration @LoadBalancerClient(name = "httpbin", configuration = TestLoadBalancerConfig.Httpbin.class) + @Import(PermitAllSecurityConfiguration.class) protected static class TestConfiguration { @Bean diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/StripPrefixStaticPortTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/StripPrefixStaticPortTests.java index 4052a3f6..2ef865cd 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/StripPrefixStaticPortTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/StripPrefixStaticPortTests.java @@ -27,10 +27,12 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.cloud.gateway.server.mvc.test.HttpbinTestcontainers; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.TestLoadBalancerConfig; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -108,6 +110,7 @@ public class StripPrefixStaticPortTests { @SpringBootConfiguration @EnableAutoConfiguration @LoadBalancerClient(name = "httpbin", configuration = TestLoadBalancerConfig.Httpbin.class) + @Import(PermitAllSecurityConfiguration.class) protected static class TestConfiguration { @Bean diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/WeightRequestPredicateIntegrationTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/WeightRequestPredicateIntegrationTests.java index a962711d..7e5070a8 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/WeightRequestPredicateIntegrationTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/WeightRequestPredicateIntegrationTests.java @@ -26,8 +26,10 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.gateway.server.mvc.test.HttpbinTestcontainers; import org.springframework.cloud.gateway.server.mvc.test.HttpbinUriResolver; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; @@ -90,6 +92,7 @@ public class WeightRequestPredicateIntegrationTests { @EnableAutoConfiguration @SpringBootConfiguration + @Import(PermitAllSecurityConfiguration.class) public static class TestConfig { public TestConfig(WeightCalculatorFilter filter) { diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/DefaultRouteFunctionHandlerTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/DefaultRouteFunctionHandlerTests.java index 14f7c956..b6fa8278 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/DefaultRouteFunctionHandlerTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/DefaultRouteFunctionHandlerTests.java @@ -27,8 +27,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import static org.assertj.core.api.Assertions.assertThat; @@ -96,6 +98,7 @@ public class DefaultRouteFunctionHandlerTests { @SpringBootConfiguration @EnableAutoConfiguration + @Import(PermitAllSecurityConfiguration.class) protected static class TestConfiguration { static boolean consumerInvoked; diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/FunctionHandlerTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/FunctionHandlerTests.java index c2090807..8d1e05a3 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/FunctionHandlerTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/FunctionHandlerTests.java @@ -26,8 +26,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.web.servlet.function.RouterFunction; import org.springframework.web.servlet.function.ServerResponse; @@ -81,6 +83,7 @@ public class FunctionHandlerTests { @SpringBootConfiguration @EnableAutoConfiguration + @Import(PermitAllSecurityConfiguration.class) protected static class TestConfiguration { @Bean diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/StreamHandlerTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/StreamHandlerTests.java index aa89417d..b189ffc8 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/StreamHandlerTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/handler/StreamHandlerTests.java @@ -31,8 +31,10 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.cloud.gateway.server.mvc.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.server.mvc.test.client.TestRestClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.web.servlet.function.RouterFunction; import org.springframework.web.servlet.function.ServerResponse; @@ -90,6 +92,7 @@ public class StreamHandlerTests { @SpringBootConfiguration @EnableAutoConfiguration + @Import(PermitAllSecurityConfiguration.class) protected static class TestConfiguration { @Bean diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/test/PermitAllSecurityConfiguration.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/test/PermitAllSecurityConfiguration.java new file mode 100644 index 00000000..fec4fc6a --- /dev/null +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/test/PermitAllSecurityConfiguration.java @@ -0,0 +1,37 @@ +/* + * Copyright 2013-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.gateway.server.mvc.test; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.web.SecurityFilterChain; + +/** + * @author Ryan Baxter + */ +@Configuration(proxyBeanMethods = false) +public class PermitAllSecurityConfiguration { + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll()).csrf(AbstractHttpConfigurer::disable); + return http.build(); + } + +} diff --git a/spring-cloud-gateway-server-mvc/src/test/resources/application-tokenrelay.yml b/spring-cloud-gateway-server-mvc/src/test/resources/application-tokenrelay.yml new file mode 100644 index 00000000..ad8c1046 --- /dev/null +++ b/spring-cloud-gateway-server-mvc/src/test/resources/application-tokenrelay.yml @@ -0,0 +1,13 @@ +spring: + cloud.gateway.server.webmvc.routes: + - id: default_route + uri: https://examplel2.com + predicates: + - Path=/** + filters: + - HttpbinUriResolver= + - TokenRelay=token + - AddResponseHeader=X-Route,weight_high_test +logging: + level: + org.springframework.cloud.gateway.server.mvc: TRACE