14

I'm trying to make HTTP requests to an AWS Elasticsearch domain protected by an IAM access policy. I need to sign these requests for them to be authorized by AWS. I'm using Jest, which in turn use Apache HttpComponents Client.

This seems to be a common use case, but I can't find what should I do so Jest can sign all requests.

Braiam
  • 1
  • 11
  • 47
  • 78
Eric Citaire
  • 4,355
  • 1
  • 29
  • 49

2 Answers2

14

I think I found it! :)

This project seems to do exactly what I want : aws-signing-request-interceptor, described as "Request Interceptor for Apache Client that signs the request for AWS. Originally created to support AWS' Elasticsearch Service using the Jest client.".

Edit : I forked the project to fit my needs (Java 7, temporary STS credentials), and it works nicely.

Here is an example of usage (here without STS temporary credentials):

String region = "us-east-1";
String service = "es";
String url = "???"; // put the AWS ElasticSearch endpoint here

DefaultAWSCredentialsProviderChain awsCredentialsProvider = new DefaultAWSCredentialsProviderChain();
final AWSSigner awsSigner = new AWSSigner(awsCredentialsProvider, region, service, () -> new LocalDateTime(DateTimeZone.UTC));

JestClientFactory factory = new JestClientFactory() {
    @Override
    protected HttpClientBuilder configureHttpClient(HttpClientBuilder builder) {
        builder.addInterceptorLast(new AWSSigningRequestInterceptor(awsSigner));
        return builder;
    }
};
factory.setHttpClientConfig(new HttpClientConfig.Builder(url)
        .multiThreaded(true)
        .build());
JestClient client = factory.getObject();
Eric Citaire
  • 4,355
  • 1
  • 29
  • 49
  • Hi Eric I am following the github link provided by you. We are facing the forbidden error. Another question is in normal jest client we pass elastic search endpoint. But here we are passing only service name and region. Can you provide sample code or guidance to solve our problem. – Mohan Shanmugam Nov 03 '16 at 18:33
  • Hi @MohanShanmugam. The forbidden error is probably due to access policy misconfiguration or bad credentials. I added an example of usage in the answer. Hope this helps. – Eric Citaire Nov 03 '16 at 21:52
  • Hi Eric thanks for reply. We use jestclient to create index, put mapping and insert records in this index creation and delete index are working fine. Put mapping and insert records shows forbidden error. When I go through all community members discussions it's look weird. We are using jest 2.0.0 and AWS Es 2.3. Do you have any clue why put mapping and insert records not works. – Mohan Shanmugam Nov 04 '16 at 20:38
  • We are running this program from AWS lambda. The lambda role have Es full permissions. We used this role ARN in elastic search policy. – Mohan Shanmugam Nov 07 '16 at 23:04
  • Hard to troubleshoot this for you without knowing the details. You should post your issue in AWS forums or contact the support. They are both of great help. – Eric Citaire Nov 08 '16 at 06:13
  • Thanks for the support i had solved this issue. Its an AWS issue – Mohan Shanmugam Nov 16 '16 at 10:49
  • Works like a charm. Thank you so much! – agentcurry May 07 '17 at 18:41
  • Got `{"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details ...` error with that. It means that signature is not correct. :( – Cherry Oct 02 '17 at 13:36
  • @Cherry check [the related documentation about this](https://docs.aws.amazon.com/general/latest/gr/signature-v4-troubleshooting.html). In particular, check that the region and the endpoint are correct. – Eric Citaire Oct 02 '17 at 15:02
  • @Eric Citaire . I am using your same appoach. But in my case i want to use STS credentials. Is there a way we can retrieve the STS credentials ? In my ES policy i have added account level access – Java Programmer Sep 17 '18 at 14:51
2

This doesn't work in case of Async request.

Update:

Ignore my previous comment. It works after adding interceptor for async requests too:

final AWSSigningRequestInterceptor requestInterceptor = new AWSSigningRequestInterceptor(awsSigner);
            factory = new JestClientFactory() {
                @Override
                protected HttpClientBuilder configureHttpClient(HttpClientBuilder builder) {
                    builder.addInterceptorLast(requestInterceptor);
                    return builder;
                }
                @Override
                protected HttpAsyncClientBuilder configureHttpClient(HttpAsyncClientBuilder builder) {
                    builder.addInterceptorLast(requestInterceptor);
                    return builder;
                }
            };
Yeshodhan Kulkarni
  • 2,844
  • 1
  • 16
  • 19