我们使用AWS V4签名机制从我们的iOS应用程序调用我们的API Gateway端点。我们在代码中嵌入了访问密钥id和密钥,这很好。显然,这不是一种安全的方式,推荐的方法是使用AWS Cognito。 我想知道我们如何使用我在Objective-C iOS代码中从AWSCredentials对象获得的临时访问密钥和秘密(以及会话密钥)来向我们的API网关端点发出安全请求。
我们尝试使用从Cognito检索到的临时访问密钥和密码来生成V4签名来代替帐户访问密钥和密钥,但这似乎不是正确的方法。使用AWS_IAM作为授权设置启用API网关方法。
这是我们得到的错误:
{ 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签名或完全绕过该过程,请您在此帮助。
答案 0 :(得分: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 或甚至范围缩小到方法级别。
答案 1 :(得分:0)
发送HTTP标头" x-amz-security-token"使用从AWSCredentials对象获取的变量sessionKey的值解决了问题:
[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。 感谢您的反馈。