简体   繁体   中英

InvalidSignatureException while using aws-sdk-js with CognitoSync service

I am using the latest version of aws-sdk-js (v2.471.0) in my web application.

User is successfully authenticated via Cognito Identity and is given a valid session. My issue is that all CognitoSync calls fail with the same error message:

InvalidSignatureException: 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.
    at Object.extractError (http://localhost:4400/scripts/libs/aws-sdk.js:166311:27)
    at Request.extractError (http://localhost:4400/scripts/libs/aws-sdk.js:166652:8)
    at Request.callListeners (http://localhost:4400/scripts/libs/aws-sdk.js:169314:20)
    at Request.emit (http://localhost:4400/scripts/libs/aws-sdk.js:169286:10)
    at Request.emit (http://localhost:4400/scripts/libs/aws-sdk.js:167947:14)
    at Request.transition (http://localhost:4400/scripts/libs/aws-sdk.js:167286:10)
    at AcceptorStateMachine.runTo (http://localhost:4400/scripts/libs/aws-sdk.js:172800:12)
    at http://localhost:4400/scripts/libs/aws-sdk.js:172812:10
    at Request.<anonymous> (http://localhost:4400/scripts/libs/aws-sdk.js:167302:9)
    at Request.<anonymous> (http://localhost:4400/scripts/libs/aws-sdk.js:167949:12)
the signature you provided.

What makes worse is that other AWS service calls, for instance to DynamoDB , work with no issues with the same credentials!

Both services use the exact same credentials to make their calls.

The cognito user role is given access to all CognitoSync actions and resources.

I have tried all the solutions on Amazon, and Github threads that were even remotely related to my issue here with no luck, as most of them are developer tools and use hard-coded and manually generated access keys for authentication where as I am authenticating users with their Cognito Identity credentials.

Here's the failing CognitoSync.listDatasets request:

Request URL: http://localhost:4400/xhr_proxy?rurl=https%3A//cognito-sync.us-east-1.amazonaws.com/identitypools/us-east-1%253A2bc13d33-35df-4da6-9c18-0e75a887eb38/identities/us-east-1%253A092beff5-9f9d-484f-a757-fc73531b0d2d/datasets
Request Method: GET
Status Code: 403 Forbidden
Remote Address: [::1]:4400
Referrer Policy: no-referrer-when-downgrade

GET /xhr_proxy?rurl=https%3A//cognito-sync.us-east-1.amazonaws.com/identitypools/us-east-1%253A2bc13d33-35df-4da6-9c18-0e75a887eb38/identities/us-east-1%253A992beff5-9f9d-484f-a757-fc73531b0d2d/datasets HTTP/1.1
Host: localhost:4400
Connection: keep-alive
Authorization: AWS4-HMAC-SHA256 Credential=GSIAZFP73J6WBXVLXVGG/20190609/us-east-1/cognito-sync/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent, Signature=5dfc5e765a9bebc22f31ba76005b177e4283aa22f51194142f6c7b12c7f911e8
Content-Type: application/json
X-Amz-Content-Sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36
x-amz-security-token: AgoGb3JpZ2luEJv...+zy5wU=
X-Amz-Date: 20190609T073401Z
X-Amz-User-Agent: aws-sdk-js/2.471.0 callback
Accept: */*
Referer: http://localhost:4400/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

And here's the successful DynamoDB.listTables request:

Request URL: http://localhost:4400/xhr_proxy?rurl=https%3A//dynamodb.us-east-1.amazonaws.com/
Request Method: POST
Status Code: 200 OK
Remote Address: [::1]:4400
Referrer Policy: no-referrer-when-downgrade

POST /xhr_proxy?rurl=https%3A//dynamodb.us-east-1.amazonaws.com/ HTTP/1.1
Host: localhost:4400
Connection: keep-alive
Content-Length: 2
Origin: http://localhost:4400
Authorization: AWS4-HMAC-SHA256 Credential=GSIAZFP73J6WBXVLXVGG/20190609/us-east-1/dynamodb/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-target;x-amz-user-agent, Signature=9ffb9c0c1d32fe18461c6398102c903d3b174f1175a7e628c2f4ca6e6a5ddf24
Content-Type: application/x-amz-json-1.0
X-Amz-Content-Sha256: 44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36
x-amz-security-token: AgoGb3JpZ2luEJv...+zy5wU=
X-Amz-Target: DynamoDB_20120810.ListTables
X-Amz-Date: 20190609T073401Z
X-Amz-User-Agent: aws-sdk-js/2.471.0 callback
Accept: */*
Referer: http://localhost:4400/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

And here's a snippet of relative parts of my code:

let credentials: AWS.CognitoIdentityCredentials = new window.aws.CognitoIdentityCredentials({
    IdentityPoolId: Config.awsIdentityPoolId,
    Logins: logins,
});

credentials.refresh((err) =>
{
    if (err) { reject(err); }
    else { resolve(); }
});

// await for credentials promise above to resolve

let params = {
    IdentityId: credentials.identityId,
    IdentityPoolId: Config.awsIdentityPoolId
}
this.dynamoDB = new window.aws.DynamoDB();
this.dynamoDB.listTables({}, (err, data) =>
{
    if (err) { console.log(err); }
    else { console.log(data); }
});

this.cognitoSync = new window.aws.CognitoSync();
this.cognitoSync.listDatasets(params, (err, data) =>
{
    if (err) { console.log(err); }
    else { console.log(data);}
});

I ended up asking my question on the library's github page since I got no answers here. I didn't get answer there either, so I tried to track down the issue in the source code of the lib.

Turns out that is a library bug, double escaping the url while generating the signature. Here's a link to my solution. https://github.com/aws/aws-sdk-js/issues/2706#issuecomment-501125092

I'll paste the solution here as well in case someone needs a hotfix now.

I solved the issue by changing the following in v4.js (or aws-sdk.js if you're using the distribution)

  canonicalString: function canonicalString() {
    var parts = [], pathname = this.request.pathname();
    if (this.serviceName !== 's3' && this.signatureVersion !== 's3v4') pathname = AWS.util.uriEscapePath(pathname);

    parts.push(this.request.method);
    parts.push(pathname);
    parts.push(this.request.search());
    parts.push(this.canonicalHeaders() + '\n');
    parts.push(this.signedHeaders());
    parts.push(this.hexEncodedBodyHash());
    return parts.join('\n');
  }

to

  canonicalString: function canonicalString() {
    var parts = [], pathname = this.request.pathname();
    if (this.serviceName !== 'cognito-sync' && this.serviceName !== 's3' && this.signatureVersion !== 's3v4') pathname = AWS.util.uriEscapePath(pathname);

    parts.push(this.request.method);
    parts.push(pathname);
    parts.push(this.request.search());
    parts.push(this.canonicalHeaders() + '\n');
    parts.push(this.signedHeaders());
    parts.push(this.hexEncodedBodyHash());
    return parts.join('\n');
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM