为什么使用 AWS 开发工具包连接到 AWS API Gateway Websocket API 时会收到 403 错误?

问题描述 投票:0回答:1

我目前正在开发 Spring 应用程序,并在尝试将消息发布到 Websocket 连接时遇到问题。

我已在 AWS API Gateway 中成功设置 Websocket API,并且可以通过 Postman 使用我的 IAM 凭证发布到特定连接。

但是,当我尝试在 Spring 应用程序中使用 Java AWS SDK 执行相同操作时,我收到 403 错误。

这是 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());

第一个请求正在尝试获取有关连接的信息。

第二个请求正在尝试向连接发送消息。两者都会返回 403 错误。

我知道我的凭据具有正确的权限,因为我可以使用相同的凭据通过 Postman 直接发送相同的请求,并且它有效。

问题是什么?

amazon-web-services aws-api-gateway aws-java-sdk-2.x
1个回答
0
投票

TLDR:使用

endpointOverride
https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}


您无需在

@connections
中指定
endpointOverride

根据 Javadoc,SDK 端点覆盖遵循以下格式:

https://{api-id}.execute-api.{region}.amazonaws.com/{stage}

不是:

https://{api-id}.execute-api.{region}.amazonaws.com/@connections/{stage}

使用 SDK 时,

getConnection
postToConnection
方法(以及
deleteConnection
方法)将自动将
@connections
附加到已部署 API 的端点。

GetConnectionRequestMarshaller.class

@SdkInternalApi
public class GetConnectionRequestMarshaller implements Marshaller<GetConnectionRequest> {
    // ...

    static {
        SDK_OPERATION_BINDING = OperationInfo
            .builder()
            .requestUri("/@connections/{connectionId}")
            .httpMethod(SdkHttpMethod.GET)
            .hasExplicitPayloadMember(false)
            .hasImplicitPayloadMembers(false)
            .hasPayloadMembers(false)
            .build();
    }
}

PostToConnectionRequestMarshaller.class

@SdkInternalApi
public class PostToConnectionRequestMarshaller implements Marshaller<PostToConnectionRequest> {
    // ...

    static {
        SDK_OPERATION_BINDING = OperationInfo
            .builder()
            .requestUri("/@connections/{connectionId}")
            .httpMethod(SdkHttpMethod.POST)
            .hasExplicitPayloadMember(true)
            .hasImplicitPayloadMembers(false)
            .hasPayloadMembers(true)
            .build();
    }
}

这应该有效:

URI endpointOverride = new URI("https://api-id.execute-api.us-west-2.amazonaws.com/stage");

ApiGatewayManagementApiClient testApiClient =
    ApiGatewayManagementApiClient
        .builder()
        .region(Region.US_WEST_2)
        .credentialsProvider(credentialsProvider)
        .endpointOverride()
        .build();

即使您在没有 SDK 的情况下手动调用 API,记录格式为:

https://{api-id}.execute-api.{region}.amazonaws.com/{stage}/@connections/{connection_id}

/@connections/{stage}
根本不起作用。

© www.soinside.com 2019 - 2024. All rights reserved.