Reputation: 1
I have an oauth2 token fetching gateway filter that I need to wire a circuit breaker in. If I can't connect to the provider or authentication fails, I need to use the fallback route.
My filter is below:
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
import org.springframework.stereotype.Component;
@Component
public class Oauth2GatewayFilterFactory extends AbstractGatewayFilterFactory<Oauth2GatewayFilterFactory.Config> {
private final ReactiveOAuth2AuthorizedClientManager authorizedClientManager;
public Oauth2GatewayFilterFactory(
ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
super(Config.class);
this.authorizedClientManager = authorizedClientManager;
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
final var clientRegistrationId = config.getClientRegistrationId();
final var oauth2Request = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistrationId)
.principal("N/A")
.build();
return authorizedClientManager.authorize(oauth2Request)
.map(authorizedClient -> exchange.mutate()
.request(r -> r.headers(
headers -> headers.set(HttpHeaders.AUTHORIZATION,
"Bearer " + authorizedClient.getAccessToken().getTokenValue())))
.build())
.defaultIfEmpty(exchange)
.flatMap(chain::filter);
};
}
public static class Config {
private String clientRegistrationId;
public String getClientRegistrationId() {
return clientRegistrationId;
}
public void setClientRegistrationId(String clientRegistrationId) {
this.clientRegistrationId = clientRegistrationId;
}
}
}
I've attempted wiring the circuit breaker into the filter factory and then doing a transformDeferred
return authorizedClientManager.authorize(oauth2Request)
.transformDeferred(CircuitBreakerOperator.of(circuitBreaker))
.map(authorizedClient -> {
but this doesn't help me.
How do I wire in the circuit breaker?
Upvotes: 0
Views: 35
Reputation: 1
I got around it without the circuit breaker by using a pattern like this:
return authorizedClientManager.authorize(oauth2Request)
.map(authorizedClient -> exchange.mutate()
.request(r -> r.headers(
headers -> headers.set(HttpHeaders.AUTHORIZATION,
"Bearer " + authorizedClient.getAccessToken().getTokenValue())))
.build())
.onErrorResume(e -> Mono.empty()) // Ignore the error
.defaultIfEmpty(exchange) // Then continue if an occurred, allowing routed request to fail with a 401
.flatMap(chain::filter);
Upvotes: 0