Consume response from a WebClient API call in spring cloud gateway filter exchange

Issue

This Content is from Stack Overflow. Question asked by Ahmed Yusuf

I am using Spring Cloud Gateway for my microservices and I am trying to make a blocking API call to another microservice within my GatewayFilter. But since spring cloud gateway is reactive, it does not allow for making blocking API Calls so I’m unable to use .block() to wait for the WebClient response.
Here is my Auth Filter.

@Component
@RequiredArgsConstructor
public class AuthFilter implements GatewayFilter {

    @Autowired
    private WebClient.Builder webClientBuilder;
    @Autowired
    private AuthenticationTokenService authenticationTokenService;



    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        final List<String> openEndpoints = List.of("/api/v1/auth/login","/api/v1/auth/refresh-token","/api/v1/user/register",
                "/api/v1/server/health-check", "/api/v1/user/health-check");
        final Predicate<ServerHttpRequest> isApiSecured = r -> openEndpoints.stream()
                .noneMatch(uri -> r.getURI().getPath().contains(uri));

        if (isApiSecured.test(request)) {
            boolean isAuthorizationHeader = request.getHeaders().containsKey(AUTHORIZATION);
            if (!isAuthorizationHeader) {
                response.setStatusCode(UNAUTHORIZED);
                return response.setComplete();
            }
            try {
                final String authHeader = Objects.requireNonNull(request.getHeaders().get(AUTHORIZATION)).get(0);
                final String[] parts = authHeader.split(" ");
                if (parts.length != 2 || !"Bearer".equals(parts[0])) {
                    throw new RuntimeException("Incorrect auth structure");
                }

                if(!request.getURI().getPath().endsWith("/refresh-token")) {
                    final String authenticationToken = parts[1];
                    final AuthenticationTokenDetails authenticationTokenDetails = authenticationTokenService
                            .parseAccessToken(authenticationToken);
                    final Long id = authenticationTokenDetails.getUserId();
                    final String uniqueId = authenticationTokenDetails.getUniqueId();
                    webClientBuilder.build()
                            .get()
                            .uri("http://PERSISTENCE-SERVICE/api/v1/user/verify?id=" +id+ "&uniqueId=" +uniqueId)
                            .retrieve()
                            .bodyToMono(Boolean.class);
                    //I am trying to consume the response from the above webclient call
                    //The goal is for me to mutate my exchange to include the result from the API call before passing
                    //the request to the downstream microservice
                }

            } catch (Exception e) {
                response.setStatusCode(FORBIDDEN);
                return response.setComplete();
            }

        }
        return chain.filter(exchange);
    }

}

I am trying to consume the response from the webclient call. The goal is for me to mutate my exchange to include the result from the API call before passing the request to the downstream microservice



Solution

This question is not yet answered, be the first one who answer using the comment. Later the confirmed answer will be published as the solution.

This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?