0

I have a service that is holding an WebClient instance:

@Service
@Getter
public class SomeApiWebClient {

    private final WebClient webClient;
    private final String someApiUrl;

    public SomeApiWebClient(@Value("${some.api.url}") String someApiUrl) {
        this.someApiUrl= someApiUrl;
        this.webClient = WebClient.builder()
                .baseUrl(someApiUrl)
                .defaultHeaders(getDefaultHttpHeaders())
                .build();
    }

    public Consumer<HttpHeaders> getDefaultHttpHeaders() {
        return headers -> {
            headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
            headers.setContentType(MediaType.APPLICATION_JSON);
        };
    }

}

To call this API from UAT/PROD environments - this is just fine. But to call it from our local machines, we need to use Client-ID and Secret HTTP headers:

public Consumer<HttpHeaders> getDefaultHttpHeaders() {
    return headers -> {
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("Client-Id", "someId");
        headers.add("Secret", "someSecret");
    };
}

I have put the someId and someSecret values into application-dev.properties:

some.api.client-id=someId
some.api.token=someSecret

Now I would like to use @Configuration combined with @ConditionalOnProperty({"some.api.client-id", "some.api.token"}) to intercept and add a filter to MDSWebClient that will add those headers when the some.api.client-id and some.api.token are present.

I have tried doing something like this:

@Configuration
@ConditionalOnProperty({"some.api.client-id", "some.api.token"})
public class MDSWebClientInterceptor implements WebFilter {

    @Value("some.api.client-id")
    private String clientId;
    @Value("some.api.token")
    private String token;

    private static final String CLIENT_ID_HEADER = "Client-Id";
    private static final String CLIENT_TOKEN_HEADER = "Secret";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        return chain.filter(
                exchange.mutate().request(
                                exchange.getRequest().mutate()
                                        .header(CLIENT_ID_HEADER, clientId)
                                        .header(CLIENT_TOKEN_HEADER, token)
                                        .build())
                        .build());
    }

}

But this doesn't work at all, and I have a hunch that if it would work, it would affect ALL WebClient instances, not just the one in SomeApiWebClient.

Is something like this even possible?

hc0re
  • 1,806
  • 2
  • 26
  • 61
  • Check if this contains any hint for solving that: https://stackoverflow.com/questions/51726943/how-to-intercept-a-request-when-using-springboot-webclient. There is an example with ConditionalOnProperty but with different condition than the one you want. – pringi Feb 17 '22 at 12:40

0 Answers0