awslabs / aws-crt-nodejs

NodeJS bindings for the AWS Common Runtime.
Apache License 2.0
38 stars 24 forks source link

Lambda@Edge SigV4Asymmetric signing issue in Typescript for S3 Multi Region Access point MRAP #416

Closed wilsonrm closed 1 year ago

wilsonrm commented 1 year ago

Hi I was trying replicate in Typescript the S3 MRAP signing based on the article https://aws.amazon.com/blogs/storage/building-an-active-active-latency-based-application-across-multiple-regions/

The specific issue I am having with is the AWS SDK for node ‘aws-crt’ 1.15.9 and nodejs18.x:

import { auth } from 'aws-crt'; import { HttpHeaders, HttpRequest } from "aws-crt/dist/native/http";

.....

const httpRequest = new HttpRequest(method, endpoint, headers); const signedHttpRequest: HttpRequest = await auth.aws_sign_request(httpRequest, config);

However the issue I have is that both calls above return an empty object {}

Typescript code:

Signing function:

async function sigV4ASignBasic(method: string, endpoint: string, headers: HttpHeaders, service: string): Promise { const httpRequest = new HttpRequest(method, endpoint, headers); console.log('httpRequest: ' + JSON.stringify(httpRequest))

const config: AwsSigningConfig = { service: service, region: "*", algorithm: auth.AwsSigningAlgorithm.SigV4Asymmetric, signature_type: auth.AwsSignatureType.HttpRequestViaHeaders, signed_body_header: auth.AwsSignedBodyHeaderType.XAmzContentSha256, provider: auth.AwsCredentialsProvider.newDefault() }; console.log('config: ' + JSON.stringify(config))

const signedHttpRequest: HttpRequest = await auth.aws_sign_request(httpRequest, config); console.log('signedHttpRequest: ' + JSON.stringify(signedHttpRequest)) return signedHttpRequest.headers; }

Called from:

console.log('method: %s, endpoint: %s, cfReadOnlyHeaders with X-Amz-Cf-Id: %s, service: %s', method, endpoint, JSON.stringify(cfReadOnlyHeaders), service)
//  # Sign the request with Signature Version 4A (SigV4A).
const authHeaders: HttpHeaders = await sigV4ASignBasic(method, endpoint, cfReadOnlyHeaders, service)

Above log:

2023-02-28T22:56:48.513+11:00

Copy 2023-02-28T11:56:48.513Z 5325804a-a907-4cb5-babe-11bc4328e5e7 INFO method: GET, endpoint: https://xxxxxxxxxxx.mrap.accesspoint.s3-global.amazonaws.com/index.html, cfReadOnlyHeaders with X-Amz-Cf-Id: { "X-Amz-Cf-Id": "8cEFzqpcNbzhCrFFmmQ94hWutlbznM7QgLVGeiH2KQHI1DpLq_swZg==" } , service: s3

Kind Regards

bretambrose commented 1 year ago

Can you enable CRT logging (https://github.com/awslabs/aws-crt-nodejs/blob/main/lib/native/io.ts#L87) and attach the log?

Also, what is implied by "Lambda@Edge" in the title? If you are using the CRT in Lambda you may want to approach packaging differently. The npm package has binaries for all supported platforms (and so is very large); if you build just for your targeted platform you may get a better experience (but probably won't be your current issue).

wilsonrm commented 1 year ago

"Lambda@Edge" means the Lambda function is running in CloudFront as an Origin request: https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html.

Please see attached log file

log-events-viewer-result.txt

bretambrose commented 1 year ago

The HTTP request and header types/classes are native objects and stringify won't get you anything useful. You can use the functional interface to pull out values you need. See https://github.com/awslabs/aws-crt-nodejs/blob/main/lib/native/auth.spec.ts#L157-L177

wilsonrm commented 1 year ago

Thanks Brett, appreciate you assistance and suggested that fixed it