Closed vahidiazar closed 6 months ago
What was the actual value of the Authorization
header sent? Double check it ended up having ap-southeast-2/es/aws4_request
and that only the signature was different. Also check what this looks like for a GET
.
Stepping back, since the GET
request is working, and PUT
is not, we can safely assume that the interceptor code is not signing the same body as the one being sent to the server, or appending a header after the signature is calculated. I'd look for what is actually being signed.
Build a sample with your code off https://github.com/dblock/opensearch-java-client-demo/tree/opensearch-2.x (feel free to PR into that project), or make a new project, and we can try to help debug.
Thanks for the help @dblock , I tried to intercept headers for a Get and Put request before and after signing in AwsRequestSigningApacheV5Interceptor. As the next step, I am going to build sample code with the repo you mentioned above.
Headers before signing for a PUT request:
Accept:application/json; charset=UTF-8,
Connection:keep-alive,
Content-Length:47,
Content-Type:application/json; charset=UTF-8,
User-Agent:opensearch-java/2.8.1 (Java/17.0.7),
x-amz-content-sha256:required
Headers after signing for a PUT request:
Accept:application/json; charset=UTF-8,
Authorization:AWS4-HMAC-SHA256 Credential=ASIA5UFMNPHYII5VG2IN/20240313/ap-southeast-2/es/aws4_request, SignedHeaders=accept;content-length;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=309bb0178cd4b780f8bfd2d43a92987dfd0880714f2fc50a8930ca6aa328b68e,
Connection:keep-alive,
Content-Length:47,
Content-Type:application/json; charset=UTF-8,
Host:abc.ap-southeast-2.es.amazonaws.com,
User-Agent:opensearch-java/2.8.1 (Java/17.0.7),
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,
X-Amz-Date:20240313T080742Z,
X-Amz-Security-Token:IQoJb3JpZ2luX2...==
Headers before signing for a GET request:
Accept:application/json; charset=UTF-8,
Connection:keep-alive,
User-Agent:opensearch-java/2.8.1 (Java/17.0.7),
x-amz-content-sha256:required
Headers after signing for a GET request:
Accept:application/json; charset=UTF-8,
Authorization:AWS4-HMAC-SHA256 Credential=ASIA5UFMNPHYII5VG2IN/20240313/ap-southeast-2/es/aws4_request, SignedHeaders=accept;host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=585c68ab6d0404437c542e0b96deb0b7628b79d737e6529fecd46de486d2b54f,
Connection:keep-alive,
Host:abc.ap-southeast-2.es.amazonaws.com,
User-Agent:opensearch-java/2.8.1 (Java/17.0.7),
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,
X-Amz-Date:20240313T080741Z,
X-Amz-Security-Token:IQoJb3JpZ2lu...==
I forked the branch and created a sample application (created a PR to the branch you mentioned) accessible here: https://github.com/vahidiazar/opensearch-java-client-demo/tree/opensearch-2.x-ApacheHttpClient5Transport
I could replicate the problem, The app has 2 sections:
Could you please have a look when you free?
The interceptor is seeing a BasicHttpRequest but only knows how to sign a ClassicHttpRequest which has a body (entity). I think this is why we can't implement support for ApacheHttpClient5TransportBuilder
in the interceptor, but I could be wrong (and @acm19 or @reta can correct me)?
The ApacheHttpClient5TransportBuilder
class is from opensearch-java. There's another dedicated transport option there called AwsSdk2Transport
which uses whatever AWS SDK uses and works out of the box. Is there a reason why you can't use that? example on main in my demo.
Another option is to create a client with org.apache.hc.client5.http.impl.async.HttpAsyncClients
, see this sample.
As @dblock, what you're experiencing is this issue: https://github.com/acm19/aws-request-signing-apache-interceptor/issues/101#issuecomment-1532174922. I'll re-open it btw, as we should either try to solve it or document that it's a limitation. Back when I checked there didn't seem to be a solution without some hacks.
In your case you're using ApacheHttpClient5TransportBuilder, which is using an async client under the hood that has this problem. If you use a sync client you won't experience the issue. And also there's @dblock recommendation about the out of the box transport, you could give that a try as well and let us know if it helped.
@vahidiazar help us with contributing to the README?
@dblock,
Thanks for the response,
Initially We were using an old ES client (Jest) which internally using ApacheHttpClient 4.
Inorder to hand 429 and internal errors, we were using HttpClientBuilder setRetryHandler
and setServiceUnavailableRetryStrategy
.
After migrating to OpenSearch client, We started to use RestClient first which current release uses ApacheHttpAsyncClient 4 which does not support setRetryHandler
and setServiceUnavailableRetryStrategy
. That's why I decided to try ApacheHttpClient5Transport
.
Regarding your question about why I'm not using AwsSdk2Transport
, I have the same problem regarding retrying with it, also not able to disable https on local integration tests.
Any suggestion you have for handling retries?
Happy to help on README, what you expect me to add there?
@vahidiazar It's the first time you mention retries - does the first PUT
request actually work, and it's the retry that fails with ApacheHttpClient5Transport
? If so that is a different bug. Can you try to put a repro together maybe by modifying my simple demo.
@dblock , Sorry if I confused you.
I just tried to clarify why I'm trying to use ApacheHttpClient5Transport
.
I created a demo here which demonstrates the bug (mentioned above) and it is not related to retry (there is not retry): https://github.com/vahidiazar/opensearch-java-client-demo/tree/opensearch-2.x-ApacheHttpClient5Transport
Thanks @vahidiazar. I'm going to close this issue as a dup of https://github.com/acm19/aws-request-signing-apache-interceptor/issues/101. Thank you for providing an example. If you want to turn it into a failing unit/integration test and PR that, I think we could get one step closer to an implementation, but I am not sure how that could work given the limitations of what the client exposes.
I am trying to sign (AWS Sig v4) opensearch requests using this library. The client library I'm using is opensearch java client and in order to use http5, I'm using ApacheHttpClient5Transport class. This is how I create a bean of
AwsRequestSigningApacheV5Interceptor
Here is how I use the interceptor:
When my applications start, GET requests works as expected, but I see the following error on PUT request:
Is this a bug in the interceptor class?