diff --git a/docs/src/main/asciidoc/spring-cloud-gateway.adoc b/docs/src/main/asciidoc/spring-cloud-gateway.adoc
index eff9bb7f..61ed3f14 100644
--- a/docs/src/main/asciidoc/spring-cloud-gateway.adoc
+++ b/docs/src/main/asciidoc/spring-cloud-gateway.adoc
@@ -1644,14 +1644,12 @@ it is proxying. To add this functionlity to gateway you need to add the
.App.java
[source,java]
----
-@Autowired
-private TokenRelayGatewayFilterFactory filterFactory;
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("resource", r -> r.path("/resource")
- .filters(f -> f.filter(filterFactory.apply()))
+ .filters(f -> f.tokenRelay())
.uri("http://localhost:9000"))
.build();
}
@@ -1680,7 +1678,7 @@ pass the authentication token downstream to the services (in this case
To enable this for Spring Cloud Gateway add the following dependencies
-- `org.springframework.cloud:spring-cloud-gateway-server-security`
+- `org.springframework.boot:spring-boot-starter-oauth2-client`
How does it work? The
{githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[filter]
@@ -1689,6 +1687,8 @@ and puts it 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].
+NOTE: A `TokenRelayGatewayFilterFactory` bean will only be created if the proper `spring.security.oauth2.client.*` properties are set which will trigger creation of a `ReactiveClientRegistrationRepository` bean.
+
NOTE: The default implementation of `ReactiveOAuth2AuthorizedClientService` used by `TokenRelayGatewayFilterFactory`
uses an in-memory data store. You will need to provide your own implementation `ReactiveOAuth2AuthorizedClientService`
if you need a more robust solution.
diff --git a/spring-cloud-gateway-server-security/pom.xml b/spring-cloud-gateway-server-security/pom.xml
deleted file mode 100644
index abb51fb4..00000000
--- a/spring-cloud-gateway-server-security/pom.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
- 4.0.0
-
-
- org.springframework.cloud
- spring-cloud-gateway
- 3.0.0-SNAPSHOT
- ..
-
- spring-cloud-gateway-server-security
- jar
- Spring Cloud Gateway Server Security
- Spring Cloud Gateway Server Security
-
- ${basedir}/..
-
-
-
-
- org.springframework.cloud
- spring-cloud-gateway-server
-
-
- org.springframework.boot
- spring-boot-starter-oauth2-client
-
-
- org.springframework.boot
- spring-boot-configuration-processor
- true
-
-
- org.springframework.boot
- spring-boot-devtools
- true
-
-
- org.springframework.boot
- spring-boot-autoconfigure-processor
- true
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.springframework.boot
- spring-boot-starter-webflux
- test
-
-
- org.junit.vintage
- junit-vintage-engine
- test
-
-
- org.junit-pioneer
- junit-pioneer
- test
-
-
- org.springframework.cloud
- spring-cloud-test-support
- test
-
-
- io.projectreactor
- reactor-test
- test
-
-
- org.assertj
- assertj-core
- test
-
-
-
diff --git a/spring-cloud-gateway-server-security/src/main/java/org/springframework/cloud/gateway/security/TokenRelayAutoConfiguration.java b/spring-cloud-gateway-server-security/src/main/java/org/springframework/cloud/gateway/security/TokenRelayAutoConfiguration.java
deleted file mode 100644
index 91379363..00000000
--- a/spring-cloud-gateway-server-security/src/main/java/org/springframework/cloud/gateway/security/TokenRelayAutoConfiguration.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2013-2014 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.security;
-
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
-import org.springframework.boot.autoconfigure.security.SecurityProperties;
-import org.springframework.cloud.gateway.filter.GatewayFilter;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
-import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
-import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
-import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
-import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
-import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
-import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
-import org.springframework.security.web.server.SecurityWebFilterChain;
-
-/**
- * @author Dave Syer
- *
- */
-@Configuration(proxyBeanMethods = false)
-@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
-@ConditionalOnClass({ GatewayFilter.class, OAuth2AuthorizedClient.class, SecurityWebFilterChain.class,
- SecurityProperties.class })
-@ConditionalOnWebApplication(type = Type.REACTIVE)
-public class TokenRelayAutoConfiguration {
-
- @Bean
- public TokenRelayGatewayFilterFactory tokenRelayGatewayFilterFactory(
- ReactiveOAuth2AuthorizedClientManager clientManager) {
- return new TokenRelayGatewayFilterFactory(clientManager);
- }
-
- @Bean
- public ReactiveOAuth2AuthorizedClientManager gatewayReactiveOAuth2AuthorizedClientManager(
- ReactiveClientRegistrationRepository clientRegistrationRepository,
- ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
- ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder
- .builder().authorizationCode().refreshToken().build();
- DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
- clientRegistrationRepository, authorizedClientRepository);
- authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
- return authorizedClientManager;
- }
-
-}
diff --git a/spring-cloud-gateway-server-security/src/main/resources/META-INF/spring.factories b/spring-cloud-gateway-server-security/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index 74a8fbe1..00000000
--- a/spring-cloud-gateway-server-security/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,3 +0,0 @@
-# Auto Configure
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-org.springframework.cloud.gateway.security.TokenRelayAutoConfiguration
diff --git a/spring-cloud-gateway-server-security/src/test/java/org/springframework/cloud/gateway/security/TokenRelayAutoConfigurationTests.java b/spring-cloud-gateway-server-security/src/test/java/org/springframework/cloud/gateway/security/TokenRelayAutoConfigurationTests.java
deleted file mode 100644
index 05e7c0b1..00000000
--- a/spring-cloud-gateway-server-security/src/test/java/org/springframework/cloud/gateway/security/TokenRelayAutoConfigurationTests.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2014-2018 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.security;
-
-import org.junit.jupiter.api.Test;
-
-import org.springframework.boot.autoconfigure.AutoConfigurations;
-import org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration;
-import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration;
-import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-/**
- * @author Spencer Gibb
- *
- */
-public class TokenRelayAutoConfigurationTests {
-
- @Test
- public void beansAreCreated() {
- new ReactiveWebApplicationContextRunner()
- .withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class,
- ReactiveOAuth2ClientAutoConfiguration.class, TokenRelayAutoConfiguration.class))
- .withPropertyValues(
- "spring.security.oauth2.client.provider[testprovider].authorization-uri=http://localhost",
- "spring.security.oauth2.client.provider[testprovider].token-uri=http://localhost/token",
- "spring.security.oauth2.client.registration[test].provider=testprovider",
- "spring.security.oauth2.client.registration[test].authorization-grant-type=authorization_code",
- "spring.security.oauth2.client.registration[test].redirect-uri=http://localhost/redirect",
- "spring.security.oauth2.client.registration[test].client-id=login-client")
- .withUserConfiguration(TestConfig.class).withPropertyValues("debug=true").run(context -> {
- assertThat(context).hasSingleBean(ReactiveOAuth2AuthorizedClientManager.class);
- assertThat(context).hasSingleBean(TokenRelayGatewayFilterFactory.class);
- });
- }
-
- @Configuration
- protected static class TestConfig {
-
- }
-
-}
diff --git a/spring-cloud-gateway-server/pom.xml b/spring-cloud-gateway-server/pom.xml
index 7f748cba..807fc763 100644
--- a/spring-cloud-gateway-server/pom.xml
+++ b/spring-cloud-gateway-server/pom.xml
@@ -27,6 +27,11 @@
org.springframework.boot
spring-boot-starter-validation
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-client
+ true
+
org.springframework.boot
spring-boot-starter-actuator
diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java
index 992e2d27..dc158736 100644
--- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java
+++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java
@@ -45,6 +45,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.NoneNestedConditions;
+import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.embedded.NettyWebServerFactoryCustomizer;
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
@@ -96,6 +97,7 @@ import org.springframework.cloud.gateway.filter.factory.SetRequestHostHeaderGate
import org.springframework.cloud.gateway.filter.factory.SetResponseHeaderGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SetStatusGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.StripPrefixGatewayFilterFactory;
+import org.springframework.cloud.gateway.filter.factory.TokenRelayGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.rewrite.GzipMessageBodyResolver;
import org.springframework.cloud.gateway.filter.factory.rewrite.MessageBodyDecoder;
import org.springframework.cloud.gateway.filter.factory.rewrite.MessageBodyEncoder;
@@ -148,6 +150,14 @@ import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.Environment;
import org.springframework.http.codec.ServerCodecConfigurer;
+import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
+import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
+import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
+import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
+import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
+import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.Validator;
@@ -831,4 +841,31 @@ public class GatewayAutoConfiguration {
}
+ @Configuration(proxyBeanMethods = false)
+ @ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
+ @ConditionalOnClass({ OAuth2AuthorizedClient.class, SecurityWebFilterChain.class, SecurityProperties.class })
+ @ConditionalOnEnabledFilter(TokenRelayGatewayFilterFactory.class)
+ @ConditionalOnBean(ReactiveClientRegistrationRepository.class)
+ protected static class TokenRelayConfiguration {
+
+ @Bean
+ public TokenRelayGatewayFilterFactory tokenRelayGatewayFilterFactory(
+ ReactiveOAuth2AuthorizedClientManager clientManager) {
+ return new TokenRelayGatewayFilterFactory(clientManager);
+ }
+
+ @Bean
+ public ReactiveOAuth2AuthorizedClientManager gatewayReactiveOAuth2AuthorizedClientManager(
+ ReactiveClientRegistrationRepository clientRegistrationRepository,
+ ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
+ ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder
+ .builder().authorizationCode().refreshToken().build();
+ DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
+ clientRegistrationRepository, authorizedClientRepository);
+ authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
+ return authorizedClientManager;
+ }
+
+ }
+
}
diff --git a/spring-cloud-gateway-server-security/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/TokenRelayGatewayFilterFactory.java
similarity index 93%
rename from spring-cloud-gateway-server-security/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java
rename to spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/TokenRelayGatewayFilterFactory.java
index e3cdf1a8..23f34b46 100644
--- a/spring-cloud-gateway-server-security/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java
+++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/TokenRelayGatewayFilterFactory.java
@@ -14,24 +14,21 @@
* limitations under the License.
*/
-package org.springframework.cloud.gateway.security;
+package org.springframework.cloud.gateway.filter.factory;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.filter.GatewayFilter;
-import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
-import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
/**
* @author Joe Grandja
*/
-@Component
public class TokenRelayGatewayFilterFactory extends AbstractGatewayFilterFactory