Sign Spring WebClient HTTP request with AWS

Viewed 755

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?

0 Answers
Related