aws-sdk-js-v3: ApiGatewayManagementApi - Stage name not included in request path - ForbiddenException
Describe the bug When making request to the ApiGatewayManagementApi the stage name is not being included in the request path resulting in a 403 response.
This is because the path is currently just of the form:
/@connections/{ConnectionId}
However, as per the documentation the path should be of the format:
/{Stage}/@connections/{ConnectionId}
Resulting in the following error:
(node:44238) UnhandledPromiseRejectionWarning: ForbiddenException: ForbiddenException
at deserializeAws_restJson1PostToConnectionCommandError (<project_root>/node_modules/@aws-sdk/client-apigatewaymanagementapi/dist/cjs/protocols/Aws_restJson1.js:287:41)
...
SDK version number 3.0.0
Is the issue in the browser/Node.js/ReactNative? I’m testing in node.js
Details of the browser/Node.js/ReactNative version
$ node -v
v12.16.1
To Reproduce (observed behavior)
const {
PostToConnectionCommand,
ApiGatewayManagementApiClient,
} = require('@aws-sdk/client-apigatewaymanagementapi');
const API_ID = '';
const REGION = '';
const STAGE = '';
const CONNECTION_ID = '';
const apiGatewayManagementApiClient = new ApiGatewayManagementApiClient({
endpoint: `https://${API_ID}.execute-api.${REGION}.amazonaws.com/${STAGE}`,
});
(async () => {
const command = new PostToConnectionCommand({
ConnectionId: CONNECTION_ID,
Data: new TextEncoder().encode('test-message'),
})
const res = await apiGatewayManagementApiClient.send(command);
console.log(res);
})();
Expected behavior Altering the request path with a middleware fixes this as a workaround:
apiGatewayManagementApiClient.middlewareStack.add(
(next) =>
async (args) => {
args.request.path = STAGE + args.request.path;
return await next(args);
},
{ step: "build" },
);
Note that this seems to happen for all of the commands within the ApiGatewayManagementApi.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 16
- Comments: 15 (2 by maintainers)
I just came across this issue too. AWS Support pointed me here (case 8373266661). Is there an ETA on when this will be resolved? I have started a new project using the v3 SDK thinking it was ready for production use but given this bug was opened five months ago it seems this may not be the case? Are we supposed to be sticking with v2 SDK for the time being?
I stumbled upon this issue as well, if it can help here is a workaround:
This appears to be fixed for me. (More specifically, after a recent update this stopped working again but after I dropped the middleware changes it works again.)
It appears to be due to #2543, specifically https://github.com/aws/aws-sdk-js-v3/commit/8ee8c9560098cc0ff7b877e857ba76d40ea571ae#diff-02accac44a940f23789960def1fcee3b352fe91e07e3e01a29aae545a7580ca2 as best I can tell, which would suggest anyone updating to 3.20.0 will need to drop the middleware changes they added.
For completeness sake and so this use case is taken into consideration, I tried setting up a custom domain (i.e.
ws.mydomain.com
) through CloudFront (to be able to use SSL Certificate with auto redirect to HTTPS/WSS), specifically setting the Origin Path to/production
so as to circumvent the stage portion of the url altogether.TLDR; the
@aws-sdk/client-apigatewaymanagementapi
package fails to post to a connection through API Gateway in WebSocket mode through CloudFront using a custom domain (i.e. posting tohttps://ws.mydomain.com/@connections/{ConnectionId}
rather thanhttps://xxxxx.execute-api.us-xxxx-n.amazonaws.com/production/@connections/{ConnectionId}
). It fails regardless ofwscat
successfully connecting to it (i.e.wscat -c wss://ws.mydomain.com
)For more detail, I followed these steps:
ws.mydomain.com
)mydomain.com
and*.mydomain.com
), in us-east-1production
(i.e.xxxxx.execute-api.us-xxxx-n.amazonaws.com/production
)xxxxx.execute-api.us-xxxx-n.amazonaws.com
and Origin Path/production
(with cache in legacy mode, virtually turned off), using a custom domainws.mydomain.com
and respective ACM certificatews.mydomain.com
sub-domain in Route53 and pointed a simple A record to the aforementioned CloudFront distributionAs I mentioned in the TLDR; this setup works just fine using other WebSocket clients, but if on my code using
aws-sdk-js-v3
I change:to:
Running
PostToConnectionCommand
generates the sameForbiddenException: ForbiddenException
error.As per the
dist
code, since the resolved path appends the following:This means that
ApiGatewayManagementApiClient
is then sending the request tohttps://ws.mydomain.com/@connections/{ConnectionId}
, which CloudFront then maps tohttps://xxxxx.execute-api.us-xxxx-n.amazonaws.com/production/@connections/{ConnectionId}
.Furthermore, I figured maybe there’s some headers that
ApiGatewayManagementApiClient
might be sending to CloudFront which are not being forwarded to API Gateway, and sure thing, it is thecontent-type
header, but even letting that one through made no difference. Also tried sending an empty body, again same error.For the time being I have resolved to edit the
Aws_restJson1.js
file underdist
and hard-coding the stage. I still do not suggest this as a workaround.Please fix this issue, I have more projects depending on WebSocket API Gateway that need to be migrated to
aws-sdk-js-v3
.This seems to be reported a lot now. There was some work done in https://github.com/aws/aws-sdk-js-v3/issues/2001 maybe join forces? @AllanZhengYP @birtles
Hi @samstradling I can confirm the stage is not displayed in Smithy model. I don’t think it would work in v2 SDK either, since the JSON model there doesn’t include the stage either.
Looks like the service doc does mention the correct uri, I will open a ticket to the service team internally to confirm if the model is correct.
Ref: P42821297