Merge pull request #3751 from jaimesf/support-client-registration-id-token-relay

Support token relay clientRegistrationId on properties
This commit is contained in:
Ryan Baxter
2025-06-03 12:05:24 -04:00
committed by GitHub
19 changed files with 235 additions and 23 deletions

View File

@@ -6,25 +6,27 @@ forwards the incoming token to outgoing resource requests. The
consumer can be a pure Client (like an SSO application) or a Resource
Server.
////
TODO: support TokenRelay clientRegistrationId
Spring Cloud Gateway Server MVC can forward OAuth2 access tokens downstream to the services
it is proxying using the `TokenRelay` filter.
The `TokenRelay` filter takes one optional parameter, `clientRegistrationId`.
The following example configures a `TokenRelay` filter:
.App.java
.RouteConfiguration.java
[source,java]
----
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("resource", r -> r.path("/resource")
.filters(f -> f.tokenRelay("myregistrationid"))
.uri("http://localhost:9000"))
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsTokenRelay() {
return route("resource")
.GET("/resource", http())
.before(uri("https://localhost:9000"))
.filter(tokenRelay("myregistrationid"))
.build();
}
}
----
@@ -46,19 +48,13 @@ spring:
----
The example above specifies a `clientRegistrationId`, which can be used to obtain and forward an OAuth2 access token for any available `ClientRegistration`.
////
Spring Cloud Gateway Server MVC can forward the OAuth2 access token of the currently authenticated user `oauth2Login()` is used to authenticate the user.
//To add this functionality to the gateway, you can omit the `clientRegistrationId` parameter like this:
To add this functionality to the gateway, you can omit the `clientRegistrationId` parameter like this:
.RouteConfiguration.java
[source,java]
----
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
import static org.springframework.cloud.gateway.server.mvc.filter.TokenRelayFilterFunctions.tokenRelay;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
@Configuration
class RouteConfiguration {
@@ -100,9 +96,9 @@ To enable this for Spring Cloud Gateway Server MVC add the following dependencie
- `org.springframework.boot:spring-boot-starter-oauth2-client`
How does it work?
// The filter extracts an OAuth2 access token from the currently authenticated user for the provided `clientRegistrationId`.
// If no `clientRegistrationId` is provided,
The currently authenticated user's own access token (obtained during login) is used and the extracted access token is placed in a request header for the downstream requests.
The filter extracts an OAuth2 access token from the currently authenticated user for the provided `clientRegistrationId`.
If no `clientRegistrationId` is provided,
the currently authenticated user's own access token (obtained during login) is used and the extracted access token is placed in a request header for the downstream requests.
//For a full working sample see https://github.com/spring-cloud-samples/sample-gateway-oauth2login[this project].

View File

@@ -104,6 +104,16 @@
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>

View File

@@ -39,6 +39,7 @@ public abstract class TokenRelayFilterFunctions {
return tokenRelay(null);
}
@Shortcut
public static HandlerFilterFunction<ServerResponse, ServerResponse> tokenRelay(String defaultClientRegistrationId) {
return (request, next) -> {
Authentication principal = (Authentication) request.servletRequest().getUserPrincipal();

View File

@@ -61,10 +61,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 +86,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,8 +147,8 @@ 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 {
@@ -317,7 +322,7 @@ public class ServerMvcIntegrationTests {
.isEqualTo(HttpStatus.TOO_MANY_REQUESTS)
.expectHeader()
.valueEquals("x-status", "201"); // .expectBody(String.class).isEqualTo("Failed
// with 201");
// with 201");
}
@Test
@@ -1026,7 +1031,8 @@ public class ServerMvcIntegrationTests {
@SpringBootConfiguration
@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 +1049,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 HandlerMappingIntrospector mvcHandlerMappingIntrospector() {
return new HandlerMappingIntrospector() {
@Override
public Filter createCacheFilter() {
return (request, response, chain) -> {
chain.doFilter(request, response);
};
}
};
}
@Bean
public AsyncProxyManager<String> caffeineProxyManager() {
Caffeine<String, RemoteBucketState> builder = (Caffeine) Caffeine.newBuilder().maximumSize(100);

View File

@@ -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;
@@ -72,6 +74,7 @@ public class VanillaRouterFunctionTests {
@SpringBootConfiguration
@EnableAutoConfiguration
@LoadBalancerClient(name = "httpbin", configuration = TestLoadBalancerConfig.Httpbin.class)
@Import(PermitAllSecurityConfiguration.class)
protected static class TestConfiguration {
@Bean

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,96 @@
/*
* 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.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;
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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