'Spring Cloud Gateway with Custom Auth Server client credentials flow with WebClient
I followed this blog How can I use client_credentials to access another oauth2 resource from a resource server? to create a WebClient which will request for token and forward it downstream to another resource server. This seems to be working fine because the code shows that it is using the WebClient.
Now, I have a Spring Cloud Gateway which would like to do that and request a token and forward it downstream to a resource server.
I have the following configuration below.
@EnableWebFluxSecurity
public class WebClientConfig {
@Bean
public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
ReactiveClientRegistrationRepository clientRegistrationRepository,
ReactiveOAuth2AuthorizedClientService authorizedClientService) {
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}
@Bean
public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
String registrationId = "custom";
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
authorizedClientManager);
oauth.setDefaultClientRegistrationId(registrationId);
return WebClient.builder()
.baseUrl("http://localhost:8888")
.filter(oauth).build();
}
@Bean
public SecurityWebFilterChain configure(ServerHttpSecurity http) {
return http
.oauth2Client()
.and()
.build();
}
}
My application.yml is below
server:
port: 8081
spring:
security:
oauth2:
client:
provider:
custom:
token-uri: http://localhost:8080/oauth/token
registration:
custom:
client-id: campaign-station-client
client-secret: password
scope: "*"
authorization-grant-type: client_credentials
cloud:
gateway:
routes:
- id: resource_server_id
uri: http://localhost:8888/
predicates:
- Path=/resourceserver/**
filters:
- RewritePath=/resourceserver/(?<segment>.*), /$\{segment}
When i call my resource server endpoint via the gateway, the gateway does not use the WebClient to retrieve the access token (eg client_credentials flow). How can i make use of this WebClient for every call to the gateway in order to forward the token downstream to the resource server?
Solution 1:[1]
You need to write a custom filter and you can pass the token from there .Look at the code for TokenGatewayFilter . That will give you a better idea. I have implemented the same .
Solution 2:[2]
That was worked for me
@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()))
.uri("http://localhost:9000"))
.build();
}
ref: https://cloud.spring.io/spring-cloud-static/Greenwich.RELEASE/multi/multi__more_detail.html
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | user16496586 |
| Solution 2 | Grissom lau |
