I would like to AWS sign my HTTP request fired by reactive WebClient of Spring. To sign the request I need access to the followings: URL, HTTP method, query parameters, headers and request body bytes.
I started with writing an ExchangeFilterFunction. Due to ClientRequest interface I can access everything there I need, except the request body:
@Component
public class AwsSigningInterceptor implements ExchangeFilterFunction
{
private final AwsHeaderSigner awsHeaderSigner;
public AwsSigningInterceptor(AwsHeaderSigner awsHeaderSigner)
{
this.awsHeaderSigner = awsHeaderSigner;
}
@Override
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next)
{
Map<String, List<String>> signingHeaders = awsHeaderSigner.createSigningHeaders(request, new byte[]{}, "es", "us-west-2"); // should pass request body bytes in place of new byte[]{}
ClientRequest.Builder requestBuilder = ClientRequest.from(request);
signingHeaders.forEach((key, value) -> requestBuilder.header(key, value.toArray(new String[0])));
return next.exchange(requestBuilder.build());
}
}
In older spring versions we used RestTemplate with a ClientHttpRequestInterceptor. In that case the bytes of the body were exposed, so signing was possible.
As I see in case of WebClient Spring handles the body as a Publisher, so I'm not sure if an ExchangeFilterFunction is a good place to start.
How should I sign the HTTP request?