0

我们使用 AWS V4 签名机制从我们的 iOS 应用程序调用我们的 API Gateway 端点。我们已经在代码中嵌入了访问密钥 ID 和密钥,运行良好。显然这不是一种安全的方式,推荐的方式是使用 AWS Cognito。我想知道我们如何使用从我的 Objective-C iOS 代码中的 AWSCredentials 对象获得的临时访问密钥和秘密(可能还有会话密钥)向我们的 API Gateway 端点发出安全请求。

我们尝试使用从 Cognito 检索到的临时访问密钥和秘密来生成 V4 签名来代替帐户访问密钥和秘密,但这似乎不是正确的方法。API Gateway 方法使用 AWS_IAM 作为授权设置启用。

这是我们得到的错误:

{ status code: 403, headers {
    Connection = "keep-alive";
    "Content-Length" = 69;
    "Content-Type" = "application/json";
    Date = "Fri, 13 Jan 2017 10:26:38 GMT";
    Via = "1.1 .....cloudfront.net (CloudFront)";
    "X-Amz-Cf-Id" = "...";
    "X-Cache" = "Error from cloudfront";
    "x-amzn-ErrorType" = UnrecognizedClientException;
    "x-amzn-RequestId" = "...";
} }

使用的 IdentityPoolId 来自在 AWS Cognito 中的联合身份下创建的身份池

AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId:@"us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"];

我们使用未经身份验证的角色,因为我们不需要任何形式的用户特定身份验证。此角色具有以下策略: AmazonAPIGatewayInvokeFullAccess AmazonAPIGatewayPushToCloudWatchLogs CloudFrontFullAccess AmazonCognitoDeveloperAuthenticatedIdentities AmazonAPIGatewayAdministrator CloudFrontReadOnlyAccess IAMReadOnlyAccess AmazonCognitoPowerUser

您能否在此处帮助我如何使用 Cognito 生成 V4 签名或完全绕过该过程。

4

2 回答 2

0

使用从 AWSCredentials 对象获取的变量 sessionKey 的值发送 HTTP 标头“x-amz-security-token”解决了这个问题:

[request setValue:sessionToken forHTTPHeaderField:@"X-Amz-Security-Token"];

AWSCredentials 对象通过以下方式检索:

[[credentialsProvider credentials] continueWithBlock:^id(AWSTask<AWSCredentials *> *task) {
        if (task.error) {
            DDLogCError(@"failed getting credentials: %@", task.error);
        }
        else {
            AWSCredentials *credentials = task.result;
        }
        return nil;
    }]

是的,已将策略精简为一项 - AmazonAPIGatewayInvokeFullAccess。感谢您的反馈。

于 2017-01-13T20:52:22.090 回答
0

看起来您收到UnrecognizedClientException作为响应,但 API Gateway 不返回UnrecognizedClientException。您是否有收到错误的请求 ID?

万一您可能忘记注册配置,您需要将配置注册到服务管理器。

AWSCognitoCredentialsProvider *creds = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId:your_cognito_pool_id];

AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:creds];

AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;

对于您的未经身份验证的角色策略,我认为您向未经身份验证的用户授予了过于强大的权限。如果您希望他们能够调用您的 API,您可以将AmazonAPIGatewayInvokeFullAccess甚至范围缩小到方法级别。

于 2017-01-13T19:17:40.807 回答