I’m currently developing a Spring application and have encountered an issue while trying to post a message to a Websocket connection.
I’ve successfully set up a Websocket API in AWS API Gateway and can post to a specific connection using my IAM credentials via Postman.
However, when I attempt to do the same using the Java AWS SDK within my Spring application, I receive a 403 error.
Here is the snippet of code in Spring:
AwsSessionCredentials awsCreds = AwsSessionCredentials.create(
"***********",
"*********",
"**********"
);
AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(awsCreds);
ApiGatewayManagementApiClient testApiClient = ApiGatewayManagementApiClient.builder()
.region(Region.US_WEST_2)
.credentialsProvider(credentialsProvider)
.endpointOverride(new URI("https://api-id.execute-api.us-west-2.amazonaws.com/@connections/stage"))
.build();
String connectionId = "********";
GetConnectionResponse getResponse = testApiClient.getConnection(GetConnectionRequest.builder()
.connectionId(connectionId)
.build());
PostToConnectionResponse postResponse = testApiClient.postToConnection(PostToConnectionRequest.builder()
.connectionId(connectionId)
.data(SdkBytes.fromUtf8String("test message from Spring"))
.build());
The 1st request is attempting to get information about the connection.
The 2nd request is attempting to send a message to the connection. Both return a 403 error.
I know that my credentials have the correct permissions as I am able to directly send the same request via Postman with the same credentials and it works.
What is the issue?
TLDR: Use
endpointOverride
value ofhttps://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}
You don't need to specify
@connections
within theendpointOverride
.Per the Javadoc, the SDK endpoint override follows the format of
not:
When using the SDK, the
getConnection
&postToConnection
methods (as well as thedeleteConnection
method) will automatically append@connections
to the endpoint of your deployed API.GetConnectionRequestMarshaller.class
:PostToConnectionRequestMarshaller.class
:This should work instead:
Even if you were to manually call the API without the SDK, the documented format is:
/@connections/{stage}
won't work at all.