title: Configuring AWS Signing in Reactive Elasticsearch Configuration
body: <p>In one of our service I tried to configure AWS signing in Spring data Reactive Elasticsearch configuration.
  Spring provides the configuring the webclient through webclientClientConfigurer</p>
  <pre><code>ClientConfiguration clientConfiguration = ClientConfiguration.builder()
    .connectedTo(&quot;localhost:9200&quot;)                      
    .usingSsl()                                                                                                    
    .withWebClientConfigurer(                                                
      webClient -&gt; {
        return webClient.mutate().filter(new AwsSigningInterceptor()).build();
      })
    . // ... other options to configure if required
    .build();
  </code></pre>
  <p>through which we can configure to sign the requests but however <a href="https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html" rel="nofollow noreferrer">AWS signing</a> it requires url, queryparams, headers and request body(in case of POST,POST) to generate the signed headers.</p>
  <p>Using this I created a simple exchange filter function to sign the request but in this function I was not able to access the request body and use it.
  Below is the Filter function i was trying to use</p>
  <pre><code>@Component
  public class AwsSigningInterceptor implements ExchangeFilterFunction
  {
      private final AwsHeaderSigner awsHeaderSigner;
  
      public AwsSigningInterceptor(AwsHeaderSigner awsHeaderSigner)
      {
          this.awsHeaderSigner = awsHeaderSigner;
      }
  
      @Override
      public Mono&lt;ClientResponse&gt; filter(ClientRequest request, ExchangeFunction next)
      {
          Map&lt;String, List&lt;String&gt;&gt; signingHeaders = awsHeaderSigner.createSigningHeaders(request, new byte[]{}, &quot;es&quot;, &quot;us-west-2&quot;); // should pass request body bytes in place of new byte[]{}
  
          ClientRequest.Builder requestBuilder = ClientRequest.from(request);
  
          signingHeaders.forEach((key, value) -&gt; requestBuilder.header(key, value.toArray(new String[0])));
  
          return next.exchange(requestBuilder.build());
      }
  }
  </code></pre>
  <p>I also tried to access the request body inside ExchangeFilterFunction using below approach but once i get the request body using below approach.</p>
  <pre><code>ClientRequest.from(newRequest.build())
              .body(
                  (outputMessage, context) -&gt; {
                    ClientHttpRequestDecorator loggingOutputMessage =
                        new ClientHttpRequestDecorator(outputMessage) {
  
                          @Override
                          public Mono&lt;Void&gt; writeWith(Publisher&lt;? extends DataBuffer&gt; body) {
                            log.info(&quot;Inside write with method&quot;);
                            body =
                                DataBufferUtils.join(body)
                                    .map(
                                        content -&gt; {
                                          // Log request body using
                                          // 'content.toString(StandardCharsets.UTF_8)'
                                          String requestBody =
                                              content.toString(StandardCharsets.UTF_8);
                                          
                                          Map&lt;String, Object&gt; signedHeaders =
                                              awsSigner.getSignedHeaders(
                                                  request.url().getPath(),
                                                  request.method().name(),
                                                  multimap,
                                                  requestHeadersMap,
                                                  Optional.of(
                                                      requestBody.getBytes(StandardCharsets.UTF_8)));
  
                                          log.info(&quot;Signed Headers generated:{}&quot;, signedHeaders);
                                          signedHeaders.forEach(
                                              (key, value) -&gt; {
                                                newRequest.header(key, value.toString());
                                              });
                                          return content;
                                        });
                            log.info(&quot;Before returning the body&quot;);
                            return super.writeWith(body);
                          }
  
                          @Override
                          public Mono&lt;Void&gt;
                              setComplete() { // This is for requests with no body (e.g. GET).
                            
                            Map&lt;String, Object&gt; signedHeaders =
                                awsSigner.getSignedHeaders(
                                    request.url().getPath(),
                                    request.method().name(),
                                    multimap,
                                    requestHeadersMap,
                                    Optional.of(&quot;&quot;.getBytes(StandardCharsets.UTF_8)));
  
                            log.info(&quot;Signed Headers generated:{}&quot;, signedHeaders);
                            signedHeaders.forEach(
                                (key, value) -&gt; {
                                  newRequest.header(key, value.toString());
                                });
  
                            return super.setComplete();
                          }
                        };
  
                    return originalBodyInserter.insert(loggingOutputMessage, context);
                  })
              .build();
  </code></pre>
  <p>But with above approach I was not able to change the request headers as adding headers throws UnsupportedOperationException inside writewith method.</p>
  <p>Has anyone used the spring data reactive elastic search and configured to sign with AWS signed headers?</p>
  <p>Any help would be highly appreciated.</p>